How to swap env file for another docker service - docker

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

Related

Containers run well independently but not in docker compose

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.

Docker Compose not reading multiple files

Using the below docker compose files, i am unable to bring up my app correctly. Docker says my LAPIS_ENV environment variable is not set, but i am setting it in my second compose file which I am expecting to be merged into the first one. I have tried including them in reverse order to no avail.
version: '2.4'
services:
backend:
mem_limit: 50mb
memswap_limit: 50mb
build:
context: ./backend
dockerfile: Dockerfile
depends_on:
- postgres
volumes:
- ./backend:/var/www
- ./data:/var/data
restart: unless-stopped
command: bash -c "/usr/local/bin/docker-entrypoint.sh ${LAPIS_ENV}"
postgres:
build:
context: ./postgres
dockerfile: Dockerfile
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_HOST_AUTH_METHOD: trust
volumes:
- postgres:/var/lib/postgresql/data
- ./postgres/pg_hba.conf:/var/lib/postgres/data/pg_hba.conf
- ./data/backup:/pgbackup
restart: unless-stopped
volumes:
postgres:
version: '2.4'
services:
backend:
environment:
LAPIS_ENV: development
ports:
- 8080:80
#!/usr/bin/env bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml up

How to share docker volume between two services with one being the source of truth?

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.

Docker-compose Error cannot locate specified Dockerfile: Dockerfile

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).

Docker compose with two files

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.

Resources