docker compose share file between containers - docker

I have nginx container and server container.
I want to edit the htpasswd file of the nginx by the server container ,
how I can access to file in another container? I use docker-compose but don't know how to access to path of another container.
I search about something like network share in windows(net use or something) but in containers.
The htpasswd file will not be on the host machine so add volume is not option(I want let the server create this file)

You can add the volume from one container in another container.
Example:
php:
image: php:fpm-alpine
container_name: php
volumes:
- .:/var/www/order
entrypoint:
- php-fpm
links:
- mysql
nginx:
image: nginx:alpine
container_name: nginx
volumes_from:
- php
volumes:
- ./build/nginx.conf:/etc/nginx/conf.d/default.conf
links:
- php
ports:
- 8080:80
Now the php volume becomes accessible in the nginx container

Related

Docker container can't talk to another container

I have a docker compose file set up with 3 separate containers (Flask, Nginx and Solr)
After starting up all 3 run successfully but my Flask application can't connect to my Solr instance and when I run:
wget -S http://localhost:8983/solr/CORE_NAME/select
I get the error "Connecting to localhost (localhost)|127.0.0.1|:8983... failed: Connection refused."
I am fairly new to docker and been around a few different forums looking at this issue but nothing has worked so far. I have tried creating a network also but running into the same issue.
Here is my docker-compose.yml.
version: "2.7"
services:
nginx:
build:
context: .
dockerfile: Dockerfile-nginx
container_name: nginx
ports:
- "80:80"
- "8181:8181"
volumes:
- ./:/opt/ee1
- ee1-logs-volume:/var/log/ee1
- ./:/usr/local/websites/ee1
- sockets-volume:/tmp
depends_on:
- flask
flask:
build:
context: .
dockerfile: Dockerfile-flask
entrypoint: ["/bin/bash", "./system/start-uwsgi-docker.bash"]
container_name: flask
user: root
restart: always
volumes:
- ./:/opt/ee1
- ./ee1config.ini:/opt/ee1config.ini
- ee1jobs-logs-volume:/var/log/ee1
- ./:/usr/local/websites/ee1
- sockets-volume:/tmp
links:
- solr
solr:
build:
context: .
dockerfile: Dockerfile-solr
container_name: solr
volumes:
- data:/var/solr
entrypoint:
- bash
- "-c"
- "precreate-core ee1_1; precreate-core ee1_2; exec solr -f"
ports:
- "8983:8983"
volumes:
sockets-volume: {}
ee1-logs-volume: {}
data:
Every docker container is - network wise - a separate host with it's own IP.
Traffic to localhost or 127.0.0.1 will definitely never leave that container.
So what you need to find out is the IP of the server container (solr) you actually want to talk to, then configure the client container (flask) accordingly. This can be done by e.g. docker inspect. Be aware that upon container restart the IPs can change. You will want to use something like DNS rather than raw IPs.
Since you use docker compose, each container for a service joins the same network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
For more details check out
https://docs.docker.com/compose/networking/
https://docs.docker.com/network/

Docker-compose Apache mapping external local directory to document root

I am pretty beginner with Docker, and I'm trying to create a local development LAMP (more exactly Apache, MariaDB, PHP) stack using docker-compose, existing Docker images from Docker hub and no Dockerfile if possible, to be used with several local web projects.
I'd like to map my local web project directory /Users/myusername/projects/myprojectname to the default document root for Apache container (which seems to be /app for the Apache image I'm using)
Here is my docker-compose.yml file:
version: "3"
services:
mariadb:
image: mariadb:10.5
container_name: mariadb
restart: always
ports:
- 8889:3306
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=localmysqluser
- MYSQL_PASSWORD=localmysqlpwd
php:
image: bitnami/php-fpm:7.4
container_name: php
ports:
- 9000:9000
volumes:
- /Users/myusername/projects/myprojectname:/app
apache:
image: bitnami/apache:latest
container_name: apache
restart: always
ports:
- 8080:80
volumes:
- ./apache-vhosts/myapp.conf:/vhosts/myapp.conf:ro
- /Users/myusername/projects/myprojectname:/app
depends_on:
- mariadb
- php
But when I do docker-compose up -d then browse to http://localhost:8080/, I get zero data. Where am I wrong? Is my docker-compose.yml configuration wrong, or is it because of system rights?
I've been looking at this similar question, but I'd prefer not using any Dockerfile if possible.
Further question: is it possible to make a local directory /Users/myusername/projects/ browsable by Apache in my local browser?
As answered by J. Song, exposed port number of this Apache Docker image is 8080, not 80.
So we just need to change port mapping of Apache service to 8080:8080 instead of 8080:80.

Share dir between host and multiple containers using docker-compose

I have 2 containers in a compose files,that i want to serve app static files through nginx.
I have read this: https://stackoverflow.com/a/43560093/7522096 and want to use host dir to share between app container and nginx container, for some reason I dont want to use named volume.
===
Using a host directory Alternately you can use a directory on the host
and mount that into the containers. This has the advantage of you
being able to work directly on the files using your tools outside of
Docker (such as your GUI text editor and other tools).
It's the same, except you don't define a volume in Docker, instead
mounting the external directory.
version: '3'
services:
nginx:
volumes:
- ./assets:/var/lib/assets
asset:
volumes:
- ./assets:/var/lib/assets
===
My docker-compose file:
version: "3.7"
services:
app:
container_name: app
restart: always
ports:
- 8888:8888
env_file:
- ./env/app.env
image: registry.gitlab.com/app/development
volumes:
- ./public/app/:/usr/app/static/
- app-log:/root/.pm2
nginx:
container_name: nginx
image: 'nginx:1.16-alpine'
restart: always
ports:
- 80:80
- 443:443
volumes:
- /home/devops/config/:/etc/nginx/conf.d/:ro
- /home/devops/ssl:/etc/nginx/ssl:ro
- ./public/app/:/etc/nginx/public/app/
depends_on:
- app
volumes:
# app-public:
app-log:
Yet when i do this in my compose, the dir always come up empty on nginx, and the static files in my app container got disappear too.
Please help, I tried a lot of ways but can not figure it out.
Thanks.
During the initialization of the container docker will bind the ./public/app directory on the host with the /usr/app/static/ directory in the container.
If the ./public/app does not exist it will be created. The bind is from the host to the container, meaning that the content of ./public/app folder is
reflected (copied) into the container and not viceversa. That's why after the initialization the static app directory is empty.
If my understanding is correct your goal is to share the application files between the app container and nginx.
Taken into consideration the above the only solution is to create the files in the volume after the volume is created. Here is an example for the relevant parts:
version: "3"
services:
app:
image: ubuntu
volumes:
- ./public/app/:/usr/app/static_copy/
entrypoint: /bin/bash
command: >
-c "mkdir /usr/app/static;
touch /usr/app/static/shared_file;
mv /usr/app/static/* /usr/app/static_copy;
rm -r /usr/app/static;
ln -sfT /usr/app/static_copy/ /usr/app/static;
exec sleep infinity"
nginx:
image: 'nginx:1.16-alpine'
volumes:
- ./public/app/:/etc/nginx/public/app/
depends_on:
- app
This will move the static files to the static_copy directory and link back those files to /usr/app/static. Those files will be shared with the host (public/app director)
and nginx container (/etc/nginx/public/app/). Adapt it to fit your needs.
In alternative you can of course use named volumes.
Hope it helps

What is a docker-compose.yml file?

I can't find a real definition of what a docker-compose file is.
Is it correct to say this:
A docker-compose file is a YAML file that allows us to deploy multiples Docker containers at the same time.
I'd like to be able to explain a bit better what a docker-compose file is.
A docker-compose.yml is a config file for Docker Compose.
It allows to deploy, combine, and configure multiple docker containers at the same time. The Docker "rule" is to outsource every single process to its own Docker container.
Take for example a simple web application: You need a server, a database, and PHP. So you can set three docker containers with Apache2, PHP, and MySQL.
The advantage of Docker Compose is easy configuration. You don't have to write a big bunch of commands into Bash. You can predefine it in the docker-compose.yml:
db:
image: mysql
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: example_db
MYSQL_USER: root
MYSQL_PASSWORD: rootpw
php:
image: php
ports:
- "80:80"
- "443:443"
volumes:
- ./SRC:/var/www/
links:
- db
As you can see in my example, I define port forwarding, volumes for external data, and links to the other Docker container. It's fast, reproducible, and not that hard to understand.
The Docker Compose file format is formally specified which enables docker-compose.yml files being executed with something else than Docker, Podman for example.
Docker Compose is a tool that allows you to deploy and manage multiple containers at the same time.
A docker-compose.yml file contains instructions on how to do that.
In this file, you instruct Docker Compose for example to:
From where to take the Dockerfile to build a particular image
Which ports you want to expose
How to link containers
Which ports you want to bind to the host machine
Docker Compose reads that file and executes commands.
It is used instead of all optional parameters when building and running a single docker container.
Example:
version: '2'
services:
nginx:
build: ./nginx
links:
- django:django
- angular:angular
ports:
- "80:80"
- "8000:8000"
- "443:443"
networks:
- my_net
django:
build: ./django
expose:
- "8000"
networks:
- my_net
angular:
build: ./angular2
links:
- django:django
expose:
- "80"
networks:
- my_net
networks:
my_net:
external:
name: my_net
This example instructs Docker Compose to:
Build nginx from path ./nginx
Links angular and django containers (so their IP in the Docker network is resolved by name)
Binds ports 80, 443, 8000 to the host machine
Add it to network my_net
(so all 3 containers are in the same network and therefore accessible from each other)
Then something similar is done for the django and angular containers.
If you would use just Docker commands, it would be something like:
docker build --name nginx .
docker run --link django:django angular:angular --expose 80 443 8000 --net my_net nginx
So while you probably don't want to type all these options and commands for each image/container, you can write a docker-compose.yml file in which you write all these instructions in a human-readable format.

How to share data from host to containers using named volumes?

I'm trying to share code from host to php and nginx containers. Here is my docker-compose.yml:
version: "3"
services:
php:
image: php:fpm
container_name: php
ports:
- 9000:9000
volumes:
- php_data:/var/www/html/
# configs
- ./php/config:/usr/local/etc/php
nginx:
image: nginx
ports:
- 80:80
volumes:
- php_data:/var/www/html
# logs
- ./nginx/logs:/var/log/nginx
# configs
- ./nginx/config/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./nginx/config/nginx.conf:/etc/nginx/nginx.conf:ro
volumes:
php_data:
./code
The error when running docker-compose up is:
ERROR: In file './docker-compose.yml', volume 'php_data' must be a
mapping not a string.
How do I make make docker-compose know, that I need ./code shared with both nginx and php containers?
Docker saying it needs a mapping, so you need to set something like ./code:{map} in your volume
I think you have 2 options here. Since you share the code map to /var/www/html on both containers.
Option 1
Set the /var/www/html map in your volume:
volumes:
php_data:
./code:/var/www/html
then change /var/www/html to / in your containers.
Option 2
volumes:
php_data:
./code:/

Resources