When I run docker-compose up I am getting following ERROR: cannot locate specified Dockerfile:Dockerfile
here is my docker-compose file:
version: "3"
services:
player-docker:
build: ./src/main/java/spring/multiple/mongo/project/player
restart: always
ports:
- 8080:8080
depends_on:
- db
game-docker:
build: ./src/main/java/spring/multiple/mongo/project/game
restart: always
ports:
- 8080:8080
depends_on:
- db
score-docker:
build: ./src/main/java/spring/multiple/mongo/project/score
restart: always
ports:
- 8080:8080
depends_on:
- db
db:
image: mongo
volumes:
- mongodata:/data/db
ports:
- "27017:27017"
restart: always
volumes:
mongodata:
and I have three Dockerfiles each for player service, game service and score service in different locations.
This is my Dockerfile:
FROM openjdk:8
COPY target/demo-0.0.1-SNAPSHOT.jar score.jar
EXPOSE 8080
ENTRYPOINT ["java","-Dspring.data.mongodb.uri=mongodb://db:27017/","-jar","-Djava.rmi.server.hostname=0.0.0.0", "score.jar"]
I think you should revise your docker-compose file similar to the following:
score-docker:
build:
context: ./
dockerfile: ./src/main/java/spring/multiple/mongo/project/score/Dockerfile
The point is, you need include your target/demo-0.0.1-SNAPSHOT.jar score.jar into the docker build context. Otherwise, the Dockerfile COPY instruction will not able to find the file.
(I suppose you have the targer folder sibling as src folder).
Related
I have an app with separated frontend and backend, each one is a subfolder. I have dockerized the front and the back separately in their folders, respectively.
Now, I'm trying to run them in the same network by using docker-compose in the root folder. The build is done successfully, but when I run it, the front container works just fine, but the back container exits with code 0.
Maybe it's worth mentioning that the container of the back is a done with a docker-compose too.
Can you help me please?
Here's how the docker-compose.yml looks like in the root folder
version: '3.7'
services:
back:
build: ./backend/
ports:
- "8000:8000"
front:
build: ./frontend/
ports:
- "80:3000"
output:
app_back_1 exited with code 0
front_1 | INFO: Accepting connections at http://localhost:3000.
Here's the docker-compose file of the backend:
version: '3.5'
services:
app:
build:
context: .
command: gunicorn backend.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_data:/vol/static
ports:
- "8000:8000"
restart: always
env_file:
- .env
depends_on:
- app-db
app-db:
image: postgres:12-alpine
ports:
- "5432:5432"
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data:rw
env_file:
- .env
proxy:
build: ./proxy
volumes:
- static_data:/vol/static
- media_data:/vol/media
restart: always
ports:
- "8008:80"
depends_on:
- app
volumes:
static_data:
media_data:
postgres_data:
If the container runs well, It should run well with identical docker image that you have built. Try docker-compose up --build --force-recreate --no-deps to recreate everything from scratch with no cache, so then if you have error in your source code the error will throw for both standalone container and compose.
I have a docker-compose.yml
services:
nextjs:
container_name: next_app
build:
context: ./
restart: on-failure
command: npm run dev
volumes:
- ./:/app
- /app/node_modules
- /app/.next
ports:
- "3000:3000"
cypress:
image: "cypress/included:9.4.1"
depends_on:
- next_app
environment:
- CYPRESS_baseUrl=http://nextjs:3000
working_dir: /e2e
volumes:
- ./e2e:/e2e
I want to change env_file for next_app from cypress service. I found solution like this
cypress:
image: "cypress/included:9.4.1"
depends_on:
- next_app
environment:
- CYPRESS_baseUrl=http://nextjs:3000
working_dir: /e2e
volumes:
- ./e2e:/e2e
next_app:
env_file: .env.test
But this solution does not work. Is it even possible ?
Try something like cp .env #docker/.env
No. In Compose (or Docker, or even more generally in Linux/Unix) there is no way for one container (process) to specify environment variables for another.
You can think of a docker-compose.yml file as a set of instructions only for running containers. If you need a specific set of containers for a specific context – you don't normally need to run Cypress in production, but this is an integration-test setup – it's fine to write a separate Compose file just for that setup.
# docker-compose.cypress.yml
# Used only for integration testing
version: '3.8'
services:
nextjs:
build: .
restart: on-failure
ports:
- "3000:3000"
env_file: .env.test # <-- specific to this test-oriented Compose file
cypress:
build: ./e2e
depends_on:
- nextjs
environment:
- CYPRESS_baseUrl=http://nextjs:3000
docker-compose -f docker-compose.cypress.yml up --build
This can also be a case where using multiple Compose files together can be a reasonable option. You can define a "standard" Compose setup that only defines the main service, and then an e2e-test Compose file that adds the Cypress container and the environment settings.
# docker-compose.yml
version: '3.8'
services:
nextjs:
image: registry.example.com/nextjs:${NEXTJS_TAG:-latest}
restart: on-failure
ports:
- '3000:3000'
# docker-compose.e2e.yaml
version: '3.8'
services:
nextjs:
# These add to the definitions in the base `docker-compose.yml`
build: .
env_file: .env.test
cypress:
# This is a brand new container for this specific setup
depends_on: [nextjs]
et: cetera # copy from question or previous Compose setup
docker-compose \
-f docker-compose.yml \
-f docker-compose.e2e.yml \
up --build
I have two services in my docker-compose:
version: '3.9'
services:
web:
build:
context: .
ports:
- 8080:8080
links:
- php
volumes:
- "html:/usr/share/nginx/html/"
php:
env_file:
- ".env"
image: php:7-fpm
volumes:
- "html:/usr/share/nginx/html/"
volumes:
html:
and a Dockerfile:
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY public_html/* /usr/share/nginx/html/
but when I run docker-compose up --build it does no update the files in the volume. I have to delete the volume for the files inside public_html to update on both services.
The volumes in your docker-compose has precedence over the files you have added in the Dockerfile.
Those containers don't take the content you are trying to add in your Dockerfile - they are taking the content from the html volume which is living in your host machine.
Those are two different techniques - mounting volume vs. adding files to an image in Dockerfile.
One solution, without using volumes might be to build both images every time:
PhpDockerfile content:
FROM php:7-fpm
COPY public_html/* /usr/share/nginx/html/
and the docker-compose.yml:
version: '3.9'
services:
web:
build:
context: .
ports:
- 8080:8080
links:
- php
php:
env_file:
- ".env"
build:
context: .
dockerfile: PhpDockerfile
EDIT:
The second approach, using volumes instead of adding them in dockerfile (will be quicker since you don't have to build each time, better for development environment):
version: '3.9'
services:
web:
build:
context: .
ports:
- 8080:8080
links:
- php
volumes:
- "./public_html/:/usr/share/nginx/html/"
php:
env_file:
- ".env"
image: php:7-fpm
volumes:
- "./public_html/:/usr/share/nginx/html/"
and then you can remove the
COPY public_html/* /usr/share/nginx/html/
from your dockerfile.
Note that you might need to use the full path instead of a relative path in the docker-compose file.
I was using docker-compose, but when I tried to build it again, this error shows, I have build this docker-compose multiple times:
ERROR: Service 'api' failed to build: max depth exceeded
I tried to execute docker system prune to clean my containers, but it didn't work.
docker-compose.yml
version: "3"
services:
client:
container_name: my_client
image: mhart/alpine-node:12
build: ./client
restart: always
ports:
- "3000:3000"
working_dir: /client
volumes:
- ./client:/client
entrypoint: ["npm", "start"]
links:
- api
networks:
- my_network
api:
container_name: my_api
build: ./api
restart: always
ports:
- "9000:9000"
environment:
DB_HOSTNAME: mysql
working_dir: /api
volumes:
- ./api:/api
depends_on:
- mysql
networks:
- my_network
mysql:
container_name: my_mysql
build: ./db
restart: always
volumes:
- /var/lib/mysql
- ./db:/db
ports:
- "3307:3306"
environment:
- MYSQL_ROOT_PASSWORD=n
- MYSQL_USER=n
- MYSQL_PASSWORD=n
- MYSQL_DATABASE=n
networks:
- my_network
command: '--default-authentication-plugin=mysql_native_password'
networks:
my_network:
driver: bridge
this is the Dockerfile:
FROM mhart/alpine-node:12
WORKDIR /api
COPY package*.json /api/
RUN npm i -G nodemon
RUN npm install
COPY . /api/
EXPOSE 9000
CMD ["npm", "run", "dev"]
any help is appreciated.
So, I figure out, I just needed to execute docker system prune -a to remove any stopped container. Now --build is working again.
This command deleted all my local docker images related to my dockerfile. After building it so many times my local storage has reached a limited, thus the error max depth exceeded.
Max depth doesn't indicate an out-of-storage-capacity error (though a prune could accidentally fix it).
Rather it indicates that the api image that you were building had too many layers.
A plausible theory is that you have a recursion caused by having this in your compose file:
image: mhart/alpine-node:12
build: ./client
and this in a Dockerfile
FROM mhart/alpine-node:12
(I'm assuming the Dockerfile in ./client is also FROM the same image).
Your build is essentially adding a few layers onto your local mhart/alpine-node:12 image every time you run it (you can confirm by running docker history mhart/alpine-node:12).
If so, you should probably rename the image in your compose file.
I have two docker-compose.yml files in separate folders.
I'd like to run the two of them in the same command, in order for the services from both to be able to talk to each other.
However, when I go to the lowest common path ancestor and try to run docker-compose with both files, here is what happens:
$ docker-compose -f ./api-folder/docker-compose.yml -f ./front-folder/docker-compose.yml up -d
ERROR: build path /projects/front-folder/api either does not exist, is not accessible, or is not a valid URL.
$ docker-compose -f ./front-folder/docker-compose.yml -f ./api-folder/docker-compose.yml up -d
ERROR: build path /projects/api-folder/app either does not exist, is not accessible, or is not a valid URL.
Here are the two docker-compose.yml files:
/projects/front-folder/docker-compose.yml
version: '2'
services:
app:
restart: always
build: ./app
environment:
NODE_ENV: 'dev'
ports:
- "4400:4400"
volumes:
- ./app:/usr/src/app
nginx:
restart: always
build: ./nginx
volumes:
- ./logs:/usr/local/var/log/nginx
links:
- app
ports:
- "80:80"
/projects/api-folder/docker-compose.yml
version: '2'
services:
api:
restart: always
build: ./api
expose:
- "4600"
volumes:
- ./api:/usr/src/app
- ./logs:/logs
nginx:
restart: always
build: ./nginx
volumes:
- ./logs:/usr/local/var/log/nginx
links:
- api
ports:
- "81:80"
networks:
- hackerz
And the directory structure:
- /projects
- /front-folder
- /app
Dockerfile
- /nginx
Dockerfile
docker-compose.yml
- /api-folder
- /api
Dockerfile
- /nginx
Dockerfile
docker-compose.yml
I'm guessing the problem is with the build paths, but what I don't understand is:
Why Docker insists on searching build: ./api in /front-folder or the other way around?
How to circumvent this problem and be able to run both files together?
DOCKERFILE
Alternate Dockerfile.
Compose uses an alternate file to build with. A build path must also be specified.
service3:
build:
context: .
dockerfile: Dockerfile-alternate
docker compose build giving custom file
This isn't how compose works (by design). See my comment here: https://github.com/docker/compose/issues/3530#issuecomment-222490501.