Ming
Ming

Reputation: 1602

dockerFile copy: Forbidden path outside the build context:

I have the following folder structure:

 - main/

     .docker-compose.yml

 - backend/

   - micro-hr/

       .dockerfile

   - rabbitmq

i have my micro-hr folder where is my main package and I have a local lib which is rabbitmq

this is my dockerfile:

FROM node:lts-alpine
#create app directory
#xx
WORKDIR /usr/src
RUN apk add --no-cache bash git
RUN touch /usr/src/.bashrc | echo "PS1='\w\$ '" >> /usr/src/.bashrc
#copy files
COPY ormconfig.ts .env package.json yarn.* ./
COPY ./rabbitmq/package.json /usr/src/rabbitmq/
#install modules lib modules
RUN cd /usr/src/api/ && npm install
#copy other files
COPY . /usr/src/api/
COPY ../rabbitmq /usr/src/rabbitmq/
#set work dir
USER node

docker-compose :

version: "3.7"
services:
  micro-hr:
    build: ./backend/micro-hr
    entrypoint: ./.docker/entrypoint.sh
    container_name: micro-hr
    environment:
      - CHOKIDAR_USEPOLLING=true
    ports:
      - 3001:3000

this is my package.json on my main package backend/micro-hr:

{
  "name": "micro-hr",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "postinstall": "npm link ../rabbitmq/",
    "postupdate": "npm link ../rabbitmq/",
    "commit": "git-cz",
    "build": "babel src --extensions \".js,.ts\" --out-dir dist --copy-files --no-copy-ignored",
    "start:dev": "ts-node-dev --inspect --respawn --transpile-only --ignore-watch node_modules -r tsconfig-paths/register src/index.ts",
    "start:debug": "node start --debug --watch",
    "start:prod": "node dist/index.ts",
    "test": "jest",
    "lint": "eslint --fix",
    "lint2": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js --config ./ormconfig.ts",
    "migration:generate": "ts-node ./node_modules/typeorm/cli.js migration:generate -n"
  },
  "devDependencies": {
    "@babel/cli": "^7.11.5",
    "@babel/core": "^7.11.5",
    "@babel/node": "^7.10.5",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-typescript": "^7.10.4",
    "@commitlint/cli": "^9.1.2",
    "@commitlint/config-conventional": "^9.1.2",
    "@types/bcryptjs": "^2.4.2",
    "@types/cookie-parser": "^1.4.2",
    "@types/cors": "^2.8.7",
    "@types/express": "^4.17.8",
    "@types/helmet": "^0.0.48",
    "@types/jest": "^26.0.13",
    "@types/pino": "^6.3.0",
    "@types/pino-http": "^5.0.5",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.0.1",
    "@typescript-eslint/parser": "^4.0.1",
    "babel-plugin-module-resolver": "^4.0.0",
    "commitizen": "^4.2.1",
    "cz-conventional-changelog": "^3.3.0",
    "eslint": "^7.8.1",
    "eslint-config-airbnb-base": "^14.2.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-config-standard": "^14.1.1",
    "eslint-import-resolver-typescript": "^2.3.0",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^3.1.4",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.1",
    "husky": "^4.2.5",
    "jest": "^26.4.2",
    "pino-pretty": "^4.2.0",
    "prettier": "^2.1.1",
    "supertest": "^4.0.2",
    "ts-jest": "^26.3.0",
    "ts-node": "^9.0.0",
    "ts-node-dev": "^1.0.0-pre.62",
    "tsconfig-paths": "^3.9.0",
    "tscpaths": "^0.0.9",
    "typescript": "^4.0.2"
  },
  "dependencies": {
    "amqplib": "^0.6.0",
    "assert": "^2.0.0",
    "bcryptjs": "^2.4.3",
    "class-transformer": "^0.3.1",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "envalid": "^6.0.2",
    "express": "^4.17.1",
    "extendable-error": "^0.1.7",
    "helmet": "^4.1.0",
    "pg": "^8.3.3",
    "pino": "^6.5.1",
    "pino-http": "^5.2.0",
    "reflect-metadata": "^0.1.13",
    "tsyringe": "^4.3.0",
    "typeorm": "^0.2.25"
  },
  "config": {
    "commitizen": {
      "path": "cz-conventional-changelog"
    }
  }
}

I don't know where I am wrong, basically I made the link in my main package to my lib with the npm link and tried to create the folders in the docker, but to no avail.

error on docker build:

Step 6/10 : COPY ../rabbitmq/package.json /usr/src/rabbitmq/ ERROR: Service 'micro-hr' failed to build: COPY failed: Forbidden path outside the build context: ../rabbitmq/package.json ()

Upvotes: 0

Views: 2268

Answers (2)

Konrad Botor
Konrad Botor

Reputation: 5033

This line in .dockerfile:

COPY ./rabbitmq/package.json /usr/src/rabbitmq/

tells Docker to find file package.json in folder rabbitmq in main directory of the build context and then copy it to the container as /usr/src/rabbitmq/

This line in .docker-compose.yml:

build: ./backend/micro-hr

sets the build context to directory backend/micro-hr relative to that file.

So if your file structure is:

main
|- .docker-compose.yml
|- backend/
   |- micro-hr/
      |-.dockerfile
   |- rabbitmq

then your telling Docker to copy backend/micro-hr/rabbitmq/package.json, which does not exist. Furthermore your rabbitmq directory is not in the build context at all, sono matter what you put into the Dockerfile it will never be found.

So you should change your .docker-compose.yml to:

version: "3.7"
services:
  micro-hr:
    build:
      context: .
      dockerfile: backend/micro-hr/.dockerfile
    entrypoint: ./.docker/entrypoint.sh
    container_name: micro-hr
    environment:
      - CHOKIDAR_USEPOLLING=true
    ports:
      - 3001:3000

and your .dockerfile to (I think, you did not specify where all those files are in your project)

FROM node:lts-alpine
#create app directory
#xx
WORKDIR /usr/src
RUN apk add --no-cache bash git
RUN touch /usr/src/.bashrc | echo "PS1='\w\$ '" >> /usr/src/.bashrc
#copy files
COPY backend/micro-hr/ormconfig.ts backend/micro-hr/.env backend/micro-hr/package.json backend/micro-hr/yarn.* ./
COPY backend/rabbitmq/package.json /usr/src/rabbitmq/
#install modules lib modules
RUN cd /usr/src/api/ && npm install
#copy other files
COPY backend/micro-hr/ /usr/src/api/
COPY backend/rabbitmq /usr/src/rabbitmq
#set work dir
USER node

As a side note, this:

USER node

sets user, not working directory.

Upvotes: 1

Karan Kumar
Karan Kumar

Reputation: 3176

You need to provide the context in your docker-compose file :

version: "3.7"
services:
  micro-hr:
    context: . # here
    build: ./backend/micro-hr
    entrypoint: ./.docker/entrypoint.sh
    container_name: micro-hr
    environment:
      - CHOKIDAR_USEPOLLING=true
    ports:
      - 3001:3000

You always need to provide the context.

Upvotes: 1

Related Questions