build contains unsupported option: 'ports' - docker

Trying to use docker-compose for the first time, but not having much luck. I have the following setup:
docker-compose version 1.8.0, build f3628c7
/home/GabeThermComposer contains the docker-compose.yml
/home/GabeThermComposer/GabeThermApache contains Dockerfile
/home/GabeThermComposer/GabeThermPHPMyAdmin contains Dockerfile
/home/GabeThermComposer/GabeThermDB contains Dockerfile and nest-init.sql
When I create docker images using the Dockerfile in each subdir, it all works without issues. I was hoping with the docker-compose.yml to do all the seperate building of images at once.
The docker-compose.yml looks like this:
version: '2'
services:
GabeThermDB:
build:
context: ./GabeThermDB
dockerfile: Dockerfile
GabeThermApache:
build:
context: ./GabeThermApache
dockerfile: Dockerfile
ports:
- "80:80"
GabeThermPHPMyAdmin:
build:
context: ./GabeThermPHPMyAdmin
dockerfile: Dockerfile
ports:
- "8080:80"
When trying to run "docker-compose up", I get the following error:
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.GabeThermPHPMyAdmin.build contains unsupported option: 'ports'
services.GabeThermApache.build contains unsupported option: 'ports'
I have no clue on what is wrong with this. I think I did exactly as other examples have shown. Btw, I do know that the "context:" and "dockerfile:" is overdone, but since I'm new, I wanted to be sure to what files I'm pointing in case I forget it automatically dives into the subdir and runs the Dockerfile.
Any help is appreciated.

You have to move the ports out of the build block.
version: '2'
services:
GabeThermDB:
build:
context: ./GabeThermDB
dockerfile: Dockerfile
GabeThermApache:
build:
context: ./GabeThermApache
dockerfile: Dockerfile
ports:
- "80:80"
GabeThermPHPMyAdmin:
build:
context: ./GabeThermPHPMyAdmin
dockerfile: Dockerfile
ports:
- "8080:80"

Related

How to make docker-compose build faster

I have two services in my docker-compose.yaml that use the same build context:
service_1:
image: 'service_1:latest'
container_name: service_1
env_file:
- ./service_dir/.env
ports:
- "8000:80"
build:
context: ./service_dir/
dockerfile: Dockerfile
volumes:
- ./service_dir/app:/app
command: /start-reload.sh
service_2:
container_name: service_2
build:
context: ./service_dir/
dockerfile: Dockerfile
command: python app/my_script.py
Building this takes forever. I assume it has something to do with the fact that the build context is taken twice to the docker daemon? I'm not sure if these commands could be run in the same service but I'd prefer to have two separate containers so I can e.g. follow service_2 logs more easily. Any suggestions for a good solution to my problem?

Service notebook has neither an image nor a build context specified. At least one must be provided

I want to use jupyter/base-notebook:latest image. Here is my docker-compose.yml:
version: "3.7"
services:
notebook:
image: jupyter/base-notebook:latest
build:
args:
- NB_USER=appuser
- NB_UID=1001
- NB_GID=101
ports:
- "3010:8888"
volumes:
- "./notebooks:/home/appuser/work"
When I run docker-compose up, I get this error:
Service notebook has neither an image nor a build context specified. At least one must be provided.
How can I solve it?
There are 2 options: use an existing image OR tell the docker-compose to build it. If both are specified, then Compose names the built image with the jupyter/base-notebook:latest.
If you want to use the jupyter/base-notebook:latest image as is, remove the build: section from your compose file and keep the image::
version: "3.7"
services:
notebook:
image: jupyter/base-notebook:latest
ports:
- "3010:8888"
volumes:
- "./notebooks:/home/appuser/work"
If you want to build a custom image, give it a name that does not conflict with the official image name(preferably) and provide a build context:
services:
notebook:
build:
context: ./<dir-that-contains-the-dockerfile>
dockerfile: Dockerfile
args:
- NB_USER=appuser
- NB_UID=1001
- NB_GID=101
image: <repo>/<img-name>:<tag>

Docker-compose build: How to build an image for production and copy an app code to image?

https://docs.docker.com/compose/production/
Removing any volume bindings for application code, so that code stays
inside the container and can’t be changed from outside
I'd like to build image for production with my app code.
I have a file docker-compose-prod.yml
version: '3'
services:
------
nginx:
build:
context: ./docker/nginx
image: my_nginx:v1
ports:
- 80:80
volumes:
- ./docker/app:/var/www/html
depends_on:
- php
------
The code of my app located in ./docker/app.
The Dockerfile located in ./docker/nginx and I can't with command COPY to copy an app code outside /docker/nginx folder.
When I run a build command I get an image without app contend in /var/www/html:
docker-compose -f docker-compose-prod.yml build
How to build an image in this case with my an app code?
You could pass the dockerfile in the build argument: https://docs.docker.com/compose/compose-file/#dockerfile
This way, I think that you can change your app context to be ./docker, and in the Dockerfile, copy the app folder to /var/www/html. This way, you no longer have to specify a volume when starting the app.
Correct config looks like:
version: '3'
services:
------
nginx:
build:
context: ./docker
dockerfile: nginx/Dockerfile-prod
image: my_nginx:v1
ports:
- 80:80
------
And the Dockerfile-prod in /docker/nginx
...
COPY ./app /var/www/html
...

Are docker environment variables shared between containers?

Newbie here. I created an empty solution, added WebApplication1 and WebApplication2. I then added docker support (Docker for Windows, Windows Containers). Compose file looks like this:
version: '3.4'
services:
webapplication1:
image: compositeapp
build:
context: .\WebApplication1
dockerfile: Dockerfile
webapplication2:
image: compositeapp
build:
context: .\WebApplication2
dockerfile: Dockerfile
So both containers are in a single image. Webapplication1 dockerfile has ENV LICENSE=abc123 and webapplication2 dockerfile has ENV LICENSE=abc456.
After building and starting the containers, I used exec -it powershell to remote into the 2 containers and did get-item env:license. Both containers returned 456.
As a newbie, I was expecting one machine to return abc123 and the other abc456. I just made up the environment name as being license, but what does one do if they need a per container environment variable?
I guess the issue you notice provides from the fact you specified the same image name for both services, which implies that they will have the same ENV variable as defined in the latest-compiled Dockerfile.
Could you try this instead?
version: '3.4'
services:
webapplication1:
image: compositeapp1
build:
context: .\WebApplication1
dockerfile: Dockerfile
webapplication2:
image: compositeapp2
build:
context: .\WebApplication2
dockerfile: Dockerfile
Anyway, even if this is working, I assume your two Dockerfile are almost the same (?), in which case I would rather suggest to use a single Dockerfile and a single image tag, but customize the environment of both services by using some environment section in your docker-compose.yml (or some env_file section, along with some external .env files...).
For example, you may want to write something like this:
version: '3.4'
services:
webapplication1:
image: compositeapp
build:
context: .\WebApplication
dockerfile: Dockerfile
environment:
- LICENSE=abc123
webapplication2:
image: compositeapp
environment:
- LICENSE=abc456
(not forgetting to remove the ENV LICENSE=... line from the Dockerfile)

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