I want to override my volume in my production environment as I don't need it there (have it on my local environment for faster development). However, adding a docker-compose.override.yml file doesn't actually "remove" my volumes (resulting in an error).
This is my docker-compose.yml file
version: '3.7'
services:
app:
image: USERNAME/PROJECT_NAME
container_name: PROJECT_NAME
volumes:
- ./:/usr/src/app
...
This is my docker-compose.override.yml file
version: '3.7'
services:
app:
volumes: []
Any reason for this behaviour or alternative approaches?
An override in compose merges the values of the override file on top of the original file, but that doesn't unset values from the original. Merging an array with an empty array is that original array. You'll likely want to switch the logic, and have an override compose file for the environment with the volume, and the original compose file for the environment without any volumes.
Related
docker-compose.yml:
version: '3.7'
services:
db:
image: mysql:8.0
docker-compose.test.yml:
version: '3.7'
services:
db:
ports:
- 3306:3306
docker-compose config does not show the port. Why?
I'm trying to display the effective compose file, means: the merge result that is also used by docker-compose up.
docker-compose version 1.25.0
According to the documentation, docker-compose will only automatically find files named docker-compose.yml and docker-compose.override.yml:
By default, Compose reads two files, a docker-compose.yml and an optional docker-compose.override.yml file. By convention, the docker-compose.yml contains your base configuration. The override file, as its name implies, can contain configuration overrides for existing services or entirely new services.
If you want to use additional compose files, you need to specify them explicitly using -f <filename>:
docker-compose up -f docker-compose.yml -f docker-compose.test.yml
By default, docker-compose finds the docker-compose.yml file. The problem you are facing is happening because the port is configured in the other file and DockerCompose doesn't know anything about it. If you want to check the configuration of the other file, you need to pass it as a parameter:
docker-compose -f ./path/to/docker-compose.test.yml config
Or you can put the port configuration on the first file like this:
version: '3.7'
services:
db:
image: mysql:8.0
ports:
- 3306:3306
And it should work just fine.
I don't know if this is possible, but is there some way to pass variables on docker-compose.yml file that are passed for example for yaml file? My idea is to segregate the environment, so I would like to pass these parameters on docker-compose.yml.
//docker-compose.yml
version: "3.3"
services:
app: app-docker
environment:
HOME_SERVER: "http://www.google.com.br"
// config.yaml
server_name: ${HOME_SERVER}
There are two articles describing using environment variable but my use case is different.
I have docker-compose file where I have 3-7 containers. Depends on situation.
version: '2'
services:
db:
image: example/db
backend:
image: example/server
frontend:
image: example/gui
Now, in above example all my images will use latest version, but I would like to control which version to deploy, therefore I want to define some variable version and use it in all my images, something like:
version: '2'
variable version=1.0.1
services:
db:
image: example/db:$version
backend:
image: example/server:$version
frontend:
image: example/gui:$version
Second example is wrong, but it shows my need what I want to achieve
In the same directory as docker-compose.yml add an environment file named .env, then specify your environment variable.
After that, add variable into your docker-compose.yml
The ${..} represents a variable in .env
Docker-compose used Interpolation Syntax ${variable} for variables and you missed that in your file.
version: '2'
services:
db:
image: example/db:${version}
backend:
image: example/server:${version}
frontend:
image: example/gui:${version}
So just pass the version to your docker-compose command
version=1.13-alpine docker-compose up
I have docker-compose.yml like below:
version: '2'
services:
micro-service:
image: some/micro-service:${SERVICE_VERSION}
env_file:
- ../all-variables/${PROFILE}/micro_service.env
ports:
- "8085:8085"
And I have two files : dev.env and stage.env where SERVICE_VERSION and PROFILE are described.
Is there any way to specify concrete file when running docker-compose up
By default docker-compose takes .env file from current dir.
Is there a way to override it or another workaround ?
As mentioned in the answer in the comments there is no way to do that as it is directly coded into the source code to use .env.
However, there a couple ways to get similar behaviour.
The first way works natively with docker-compose, which would be to use docker-compose override files.
So in your case you could have your base docker-compose.yml file like this:
version: '2'
services:
micro-service:
image: some/micro-service:1.0.0
ports:
- "8085:8085"
Then you can define a docker-compose-dev.yml file:
version: '2'
services:
micro-service:
image: some/micro-service:dev
env_file:
- ../all-variables/dev/micro_service.env
Then you can run the following command
$ docker-compose up -f docker-compose.yml -f docker-compose-dev.yml up
If you do this the values in docker-compose-dev.yml will override those in docker-compose.yml. So instead of using image some/micro-service:1.0.0 it will use the image defined in docker-compose-dev.yml.
The second way would be to use docker-app. Which is a new experimental utility from the Docker team.
Basically you will create a dockerapp file that would look like this:
version: 0.0.1
name: app
---
version: '2'
services:
micro-service:
image: some/micro-service:${SERVICE_VERSION}
env_file:
- ../all-variables/${PROFILE}/micro_service.env
ports:
- "8085:8085"
---
SERVICE_VERSION: latest
PROFILE: default
Then if you convert your .env files to .yml render the compose file with the correct variables using docker-app.
docker-app render -f dev.yml | docker-compose -f - up
Hopefully this is helpful, I am going through a similar issue when working with multiple environments with docker-compose.
For production deployment, I don't want shared volumes. So, I have an override file but this does not remove the volumes.
Is there a way to remove shared volumes in an override file? I'd like to avoid having an override just for development, because that seems clunky to use.
This is my docker-compose.yml:
version: '2'
# other services defined here
services:
web:
build:
context: .
# other configuration
volumes:
- .:${APP_DIR}
And my docker-compose.prod.yml:
version: '2'
services:
web:
volumes: []
restart: always
I'm assuming you want to use docker-compose up to start the development version, and have a second config file to extend it for production.
If you want to make sure to override volumes completely, use a third config file, docker-compose.override.yml. Put all your volume definitions for development in there.
docker-compose up extends the base config with this file by default. But when you do something like docker-compose -f docker-compose.yml -f production.yml, the docker-compose.override.yml file won't be loaded, and you'll get only the volumes from the production file.
When merging a list entry in docker-compose, it adds new maps but doesn't remove existing volume mappings.
You can implement this by either making dev have the override file, or up to version 2.1 you can extend a common docker file rather than applying overrides which lets to devs point to a single file.
This could be your docker-compose.yml:
version: '2'
# other services defined here
services:
web:
extends:
file: docker-compose.prod.yml
service: web
build:
context: .
restart: no
volumes:
- .:${APP_DIR}
And your docker-compose.prod.yml would contain all the common configuration and prod settings:
version: '2'
services:
web:
# other configuration
restart: always