This question already has an answer here:
Docker is not creating new container but recreates running one
(1 answer)
Closed 1 year ago.
I wanted to use docker-compose to spin up new instances of my containers, but with slightly different parameters, so I essentially copied the entire project folder, made changes to my Docker compose file, and did docker-compose up --build but no matter which project folder I run that in, it only recreates the containers rather than spinning up new ones.
Below is my compose file. In one project folder it's this, and in the other, I changed container-name to app-test-client and app-test-api as well as changing the ports (e.g. 8080:80), so why does it recreate instead of spinning up new containers? I want to see both app-client and app-test-client running.
version: '3.2'
services:
client:
build:
context: ./client
container_name: app-client
ports:
- '80:80'
- '5432:5432'
- '443:443'
links:
- api
api:
build:
context: ./api
container_name: app-api
volumes:
- ~/.ssh:/root/.ssh
environment:
# read from ./.env file if it exists
- EDR_ENVIRONMENT=${EDR_ENV}
- SAS_ENVIRONMENT=${SAS_ENV}
command: ['node', '.']
The name is based on the service name, not the container name.
version: '3.2'
services:
client-test:
...
links:
- api
api-test:
...
You can also pass the parameter p to change the project name
Related
Docker doesn't use the latest code after running git checkout <non_master_branch>, while I can see it in the vscode.
I am using the following docker-compose file:
version: '2'
volumes:
pgdata:
backend_app:
services:
nginx:
container_name: nginx-angular-dev
image: nginx-angular-dev
build:
context: ./frontend
dockerfile: /.docker/nginx.dockerfile
ports:
- "80:80"
- "443:443"
depends_on:
- web
web:
container_name: django-app-dev
image: django-app-dev
build:
context: ./backend
dockerfile: /django.dockerfile
command: ["./wait-for-postgres.sh", "db", "./django-entrypoint.sh"]
volumes:
- backend_app:/code
ports:
- "8000:8000"
depends_on:
- db
env_file: .env
environment:
FRONTEND_BASE_URL: http://192.168.99.100/
BACKEND_BASE_URL: http://192.168.99.100/api/
MODE_ENV: DOCKER_DEV
db:
container_name: django-db
image: postgres:10
env_file: .env
volumes:
- pgdata:/var/lib/postgresql/data
I have tried docker-compose build --no-cache, followed by docker-compose up --force-recreate but it didn't solve the problem.
What is the root of my problem?
Your volumes: are causing problems. Docker volumes aren't intended to hold code, and you should delete the volume declarations that mention backend_app:.
Your docker-compose.yml file says in part:
volumes:
backend_app:
services:
web:
volumes:
- backend_app:/code
backend_app is a named volume: it keeps data that must be persisted across container runs. If the volume doesn't exist yet the first time then data will be copied into it from the image, but after that, Docker considers it to contain critical user data that must not be updated.
If you keep code or libraries in a Docker volume, Docker will never update it, even if the underlying image changes. This is a common problem in JavaScript applications that mount an anonymous volume on their node_modules directory.
As a temporary workaround, if you docker-compose down -v, it will delete all of the volumes, including the one with your code in it, and the next time you start it will get recreated from the image.
The best solution is to simply not use a volume here at all. Delete the lines above from your docker-compose.yml file. Develop and test your application in a non-Docker environment, and when you're ready to do integration testing, run docker-compose up --build. Your code will live in the image, and an ordinary docker build will produce a new image with new code.
This question already has an answer here:
Build a single image based on docker compose containers
(1 answer)
Closed 9 months ago.
I have an application composed of a front end, a back end and a mongodb database, each of these dockerized in a container. When I build them with docker compose I have as many images as parts in my application (3).
Is there any way to build a single container from these 3 images and therefore a single image?
Thanks
You can write a Dockerfile if you want to run your application as a single container. it will give you single image as well.
I guess you could do this if you really wanted to. The preferred way is to use docker-compose for this. I would suggest that you create a docker-compose.yml file that helps you setup this:
nginx->frontend (possibly with server side rendering) -> backend -> mongodb
The idea behind docker-compose is to easily get that multi container application up and running using a docker-compose.yml file , then you can just bring up the application with:
$ docker-compose up
You could it setup with something like this:
(This is a hypothetical docker-compose.yml file, but with your correct values it should work. Let me know if you have any questions:
version: '2'
services:
frontend-container:
image: frontend:latest
links:
- backend-container
environment:
- DEBUG=True
restart: always
environment:
- BASE_HOST=http://backend-container:8000/
backend-container:
image: nodejs-backend:latest
links:
- mongodb
environment:
- NODE_ENV=production
- BASE_HOST=http://django-container:8000/
restart: always
mongodb:
image: mongo:latest
container_name: "mongodb"
environment:
- MONGO_DATA_DIR=/data/db
- MONGO_LOG_DIR=/dev/null
volumes:
- ./data/db:/data/db
command: mongod --smallfiles --logpath=/dev/null
nginx-container:
image: nginx-container-custom-config:latest
links:
- frontend-container
ports:
- "80:80"
I'm trying to connect two containers with a docker-compose-yml, but it isn't working. This is my docker-compose.yml file:
version: "3"
services:
datapower:
build: .
ports:
- "9090:9090"
depends_on:
- db
db:
image: "microsoft/mssql-server-linux:2017-latest"
environment:
SA_PASSWORD: "your_password"
ACCEPT_EULA: "Y"
ports:
- "1433:1433"
When I make:
docker-compose up
This up my two containers. Then I stop one container and then I run the same container stoped independiently like:
docker-compose run -u root --name nameofcontainer 'name of container named in docker-compose.yml'
With this, the connection of the containers works. Exists a method to configure my docker-compose.yml to connect my containers like root without stop a container and run independently?
Update:
There exists the user property that can be set in the compose file. This is documented in docker-compose file reference.
...
services:
datapower:
build: .
user: root
ports:
- "9090:9090"
depends_on:
- db
...
Setting both a User AND a Group in docker-compose.yml:
Discovered another way to set not only the user but also the group in a docker-compose.yml file which is NOT documented in the Docker Compose File Reference #yamenk helpfully provides in the accepted answer.
I needed to raise a container expressly setting both a user AND a group and found that the user: parameter in docker-compose.yml can be populated as a UID:GID mapping delimited by a colon.
Below is a snippet from my docker-compose.yml file where this form was tested and found to work correctly:
services:
zabbix-agent:
image: zabbix/zabbix-agent2:ubuntu-6.0-latest
container_name: DockerHost1-zabbix-agent2
user: 0:0
<SNIP>
Reference:
https://github.com/zabbix/zabbix-docker/issues/710
Hope this saves others wasted cycles looking for this!
I have 2 applications that are separate codebases, and they each have their own database on the same db server instance.
I am trying to replicate this in docker, locally on my laptop. I want to be able to have both apps use the same database instance.
I would like
both apps to start in docker at the same time
both apps to be able to access the database on localhost
the database data is persisted
be able to view the data in the database using an IDE on localhost
So each of my apps has its own dockerfile and docker-compose file.
On app1, I start the docker instance of the app which is tied to the database. It all starts fine.
When I try to start app2, I get the following error:
ERROR: for app2_mssql_1 Cannot start service mssql: driver failed programming external connectivity on endpoint app2_mssql_1 (12d550c8f032ccdbe67e02445a0b87bff2b2306d03da1d14ad5369472a200620): Bind for 0.0.0.0:1433 failed: port is already allocated
How can i have them both running at the same time? BOTH apps need to be able to access each others database tables!
Here is the docker-compose.yml files
app1:
version: "3"
services:
web:
build:
context: .
args:
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- mssql
mssql:
image: 'microsoft/mssql-server-linux'
ports:
- '1433:1433'
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=P455w0rd!
volumes:
- app1_db:/var/lib/mssql/data
volumes:
app1_db:
and here is app2:
version: "3"
services:
web:
build:
context: .
args:
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- mssql
mssql:
image: 'microsoft/mssql-server-linux'
ports:
- '1433:1433'
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=P455w0rd!
volumes:
- app2_db:/var/lib/mssql/data
volumes:
app2_db:
Should I be using the same volume in each docker-compose file?
I guess the problem is in each app i am spinning up 2 different db instances, when in reality I guess i just want one, and it be used by all my apps?
The ports part in docker-compose file will bound the container port to host's port which causes port conflict in your case.
You need to remove the ports part from at least one of the compose file. This way, docker-compose can be up for both. And you can have access to both app at same time. But remember both apps will be placed in separate network bridges.
How docker-compose up works:
Suppose your app is in a directory called myapp, and your docker-compose.yml
When you run docker-compose up, the following happens:
A network called myapp_default is created.
A container is created using web’s configuration. It joins the network myapp_default under the name web.
A container is created using db’s configuration. It joins the network myapp_default under the name db.
If you run the second docker-compose.yml in different folder myapp2, then the nework will be myapp2_default.
Current configuration creates two volumes, two datebase containers and two apps. If you can make them run in the same network and run database as the single container it will work.
I don't think you are expecting two database container two two volumes.
Approach 1:
docker-compose.yml as a single compose.
version: "3"
services:
app1:
build:
context: .
args:
volumes:
- .:/app # give the path depending up on the docker file of app1.
ports:
- "3030:3000"
depends_on:
- mssql
app2:
build:
context: .
args:
volumes:
- .:/app # give the path depending up on the docker file of app2.
ports:
- "3032:3000"
depends_on:
- mssql
mssql:
image: 'microsoft/mssql-server-linux'
ports:
- '1433:1433'
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=SqlServer1234!
volumes:
- app_docker_db:/var/lib/mssql/data
volumes:
app_docker_db:
Approach 2:
To Isolate it further, still want to run them as the sepeare composefiles, create three compose file with network.
docker-compose.yml for database with network
version: "3"
services:
mssql:
image: 'microsoft/mssql-server-linux'
ports:
- '1433:1433'
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=SqlServer1234!
volumes:
- app_docker_db:/var/lib/mssql/data
networks:
- test_network
volumes:
app_docker_db
networks:
test_network:
docker-ompose.yml for app1
remove the database container and add below lines to your compose file
version: "3"
services:
app1:
build:
context: .
args:
volumes:
- .:/app # give the path depending up on the docker file of app1.
ports:
- "3030:3000"
networks:
default:
external:
name: my-pre-existing-network
Do the same for another docker-compose by replacing the docker-compose file.
There are many other option to create docker-compose files. Configure the default network and Use a pre-existing network
You're exposing the same port (1433) two times to the host machine. (This is what "ports:..." does). This is not possible as it would block the same port on your host (That's what the message says).
I think the most common way in these cases is that you link your db's to your apps. (See https://docs.docker.com/compose/compose-file/#links). By doing this your applications can still access the databases on their common ports (1433), but the databases are not accessible from the host anymore (only from the container that is linked to it).
Another error I see in your docker compose file is that both applications are exposed by the same ports. This is also not possible for the same reason. I would suggest that you change one of them to "3000:3001", so you can access this application on port 3001.
I want to have two docker-compose files, where one overrides another.
(The motivation comes from Docker Compose Docs)
The use case comes from the buildbot environment. The first docker-compose file should define a simple service. This is a service that is going to be tested. Let's take
version: '2'
services:
service-node:
build:
context: ./res
dockerfile: Dockerfile
image: my/server
env_file: .env
The second docker-compose file (let's name it docker-compose.test.yml) overrides the service-node to add a buildbot worker feature, and creates the second container, i.e. buildbot master node, that is going to control testing machinery. Let's take
version: '2'
services:
service-node:
build:
context: ./res
dockerfile: buildbot.worker.Dockerfile
image: my/buildbot-worker
container_name: bb-worker
env_file: ./res/buildbot.worker.env
environment:
- BB_RES_DIR=/var/lib/buildbot
networks:
testlab:
aliases:
- bb-worker
volumes:
- ./vol/bldbot/worker:/home/bldbotworker
depends_on:
- bb-master
bb-master:
build:
context: ./res
dockerfile: buildbot.master.Dockerfile
image: my/buildbot-master
container_name: bb-master
env_file: ./res/buildbot.master.env
environment:
- BB_RES_DIR=/var/lib/buildbot
networks:
- testlab
expose:
- "9989"
volumes:
- ./vol/bldbot/master:/var/lib/buildbot
networks:
testlab:
driver: bridge
Generally this configuration works, i.e. the command
docker-compose -f docker-compose.yml -f docker-compose.test.yml up -d
builds both images and runs both containers, but there is one shortcoming, i.e. the command
docker-compose ps
shows only one service, bb-worker. At the same time
docker ps
shows both.
Furthermore, the command
docker-compose down
stops only one service, and outputs the message/warning Found orphan containers. Of course, the message refers to bb-master.
How can I override the basic docker-compose.yml file to be able to add additional non-orphan service?
You need to run all docker-compose commands with the flags, e.g.:
docker-compose -f docker-compose.yml -f docker-compose.test.yml down
Alternatively, you can make this the default by writing the following to a .env file in the same folder:
COMPOSE_FILE=docker-compose.yml:docker-compose.test.yml
NOTE:
In windows you need tu use ";" as the separator (#louisvno)