How to connect to another docker service from one docker service in a docker swarm cluster? - api

In the docker swarm cluster, launched two services:
sv_web
sv_api
The stack deploy file of web is:
version: "3"
services:
web:
image: XXX/sv_web:latest
ports:
- "80:80"
networks:
- webnet
networks:
webnet:
Deploy:
docker stack deploy -c ~/docker-compose-web.yml sv
The stack deploy file of api is:
version: "3"
services:
web:
image: XXX/sv_api:latest
ports:
- "81:81"
networks:
- webnet
networks:
webnet:
Deploy:
docker stack deploy -c ~/docker-compose-api.yml sv
Now want to connect sv_api service inside the sv_web application. Tried to write:
api_server = "sv_api:81"
But can't connect the sv_api service after deploying it. If use the real IP of the host in the cluster, it can be found: [HOST]:81.
So how to connect to the API service from web service in this way?

For connect you should using
depends_on
services:
some_service:
image: link
depends_on:
-api
api:
image: link
More info at docs: docker docs

Related

Java Application on Docker (MySQL + Rabbit)

I am making an REST API which has a POST method which accepts a String as JSON and then sends it over RabbitMQ Topic and then a consumer is converting into entity and saving into a MySQL db.
Everything is running fine locally, but my task is to upload it on Docker and to be run online.
When I try to change "localhost" in properties with container names my Maven build fails....
How can i fix that?
I am putting my .properties:
spring.main.allow-bean-definition-overriding=true
spring.datasource.url=jdbc:mysql://localhost:3306/rabbit_messages?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=1234
spring.rabbitmq.host = 127.0.0.1
spring.rabbitmq.port = 5672
spring.rabbitmq.username = guest
spring.rabbitmq.password = guest
and my docker-compose:
version: '3'
services:
my-app:
container_name: myapp
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
links:
- rabbitmq
- mysql
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3307/rabbit_messages?createDatabaseIfNotExist=true
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=1234
- SPRING_RABBITMQ_HOST=rabbitmq
depends_on:
- rabbitmq
- mysql
java:
image: openjdk:latest
container_name: openjdk
rabbitmq:
image: rabbitmq:3-management
container_name: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
erlang:
image: erlang:latest
container_name: erlang
mysql:
image: mysql:latest
container_name: mysql
ports:
- "3307:3307"
environment:
- MYSQL_DATABASE=rabbit_messages
- MYSQL_ROOT_PASSWORD=1234
- MYSQL_PASSWORD=1234
restart: on-failure

How to setup rabbitmq service with Github Actions?

I am trying to set up Github Actions CI for an app that is using RabbitMQ.
RabbitMQ container is started using:
services:
rabbitmq:
image: rabbitmq:3-management
ports:
- 5672:5672
But now I need to configure it with smth like rabbitmqctl add_user user password.
How can it be done? Should I be using rabbitmq container here at all?
As this is using the rabbitmq Docker image, you can configure user credentials by passing in the RABBITMQ_DEFAULT_USER and RABBITMQ_DEFAULT_PASS environment variables.
rabbitmq:
image: rabbitmq
env:
RABBITMQ_DEFAULT_USER: craiga
RABBITMQ_DEFAULT_PASS: security_is_important
ports:
- 5672:5672
If you have trouble connecting to RabbitMQ, try with a dynamic port.
Use this:
jobs:
test:
runs-on: ubuntu-latest
services:
rabbitmq:
image: rabbitmq:3.8
env:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
ports:
- 5672
steps:
- name: Run Tests
run: |
python manage.py test
env:
RABBITMQ_HOST: 127.0.0.1
RABBITMQ_PORT: ${{ job.services.rabbitmq.ports['5672'] }}

How can i use traefik2.0 in docker swarm, i don't know which labels ishould use

I want use traefik2.0 publish port 80 and 7000, the port 7000 is for frp(TCP). Now i am testing locally with 2.0 doc, i am using example on quick start but not running.
This is my docker compose file.
version: '3'
services:
reverse-proxy:
image: traefik:v2.0 # The official v2.0 Traefik docker image
command:
- "--api"
- "--entrypoints='Name:http Address::80'"
- "--providers.docker" # Enables the web UI and tells Traefik to listen to docker
- "--providers.docker.swarmmode=true"
- "--providers.docker.watch=true"
ports:
- "80:80" # The HTTP port
- "8080:8080" # The Web UI (enabled by --api)
networks:
- traefik-net
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
labels:
- traefik.enable=false
volumes:
- /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
whoami:
image: containous/whoami # A container that exposes an API to show its IP address
networks:
- traefik-net
deploy:
labels:
- "traefik.http.routers.whoami.tls=true"
- "traefik.http.routers.whoami.entrypoints=https"
- "traefik.http.routers.whoami.rule=Host(`whoami.domain.com`)"
- "traefik.http.middlewares.whoami.redirectscheme.scheme=https"
networks:
traefik-net:
external: true
i expect which labels used on traefik2.0 can work
You're almost there!
Replace
- "--entrypoints='Name:http Address::80'"
with
- "--entryPoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
Enable the dashboard in a non-production environment. You'll also need to replace
- "--api" with
- "--api.insecure=true"
One of the labels of whoami has a mistake. There is no https entrypoint, it's now called websecure. So change
- "traefik.http.routers.whoami.entrypoints=https"
with
- "traefik.http.routers.whoami.entrypoints=websecure"
And finally expose the internal port that the whoami app is running on.
By adding this to the label of whoami
- traefik.http.services.whoami-service.loadbalancer.server.port=80
You should be able to verify it using the traefik dashboard on localhost:8080

Running multiple docker-compose files with nginx reverse proxy

I asked a question here and got part of my problem solved, but I was advised to create another question because it started to get a bit lengthy in the comments.
I'm trying to use docker to run multiple PHP,MySQL & Apache based apps on my Mac, all of which would use different docker-compose.yml files (more details in the post I linked). I have quite a few repositories, some of which communicate with one another, and not all of them are the same PHP version. Because of this, I don't think it's wise for me to cram 20+ separate repositories into one single docker-compose.yml file. I'd like to have separate docker-compose.yml files for each repository and I want to be able to use an /etc/hosts entry for each app so that I don't have to specify the port. Ex: I would access 2 different repositories such as http://dockertest.com and http://dockertest2.com (using /etc/hosts entries), rather than having to specify the port like http://dockertest.com:8080 and http://dockertest.com:8081.
Using the accepted answer from my other post I was able to get one app running at a time (one docker-compose.yml file), but if I try to launch another with docker-compose up -d it results in an error because port 80 is already taken. How can I runn multiple docker apps at the same time, each with their own docker-compose.yml files and without having to specify the port in the url?
Here's a docker-compose.yml file for the app I made. In my /etc/hosts I have 127.0.0.1 dockertest.com
version: "3.3"
services:
php:
build: './php/'
networks:
- backend
volumes:
- ./public_html/:/var/www/html/
apache:
build: './apache/'
depends_on:
- php
- mysql
networks:
- frontend
- backend
volumes:
- ./public_html/:/var/www/html/
environment:
- VIRTUAL_HOST=dockertest.com
mysql:
image: mysql:5.6.40
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
nginx-proxy:
image: jwilder/nginx-proxy
networks:
- backend
ports:
- 80:80
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
frontend:
backend:
I would suggest to extract the nginx-proxy to a separate docker-compose.yml and create a repository for the "reverse proxy" configuration with the following:
A file with extra contents to add to /etc/hosts
127.0.0.1 dockertest.com
127.0.0.1 anothertest.com
127.0.0.1 third-domain.net
And a docker-compose.yml which will have only the reverse proxy
version: "3.3"
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
Next, as you already mentioned, create a docker-compose.yml for each of your repositories that act as web endpoints. You will need to add VIRTUAL_HOST env var to the services that serve your applications (eg. Apache).
The nginx-proxy container can run in "permanent mode", as it has a small footprint. This way whenever you start a new container with VIRTUAL_HOST env var, the configuration of nginx-proxy will be automatically updated to include the new local domain. (You will still have to update /etc/hosts with the new entry).
If you decide to use networks, your web endpoint containers will have to be in the same network as nginx-proxy, so your docker-compose files will have to be modified similar to this:
# nginx-proxy/docker-compose.yml
version: "3.3"
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
networks:
- reverse-proxy
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
reverse-proxy:
# service1/docker-compose.yml
version: "3.3"
services:
php1:
...
networks:
- backend1
apache1:
...
networks:
- nginx-proxy_reverse-proxy
- backend1
environment:
- VIRTUAL_HOST=dockertest.com
mysql1:
...
networks:
- backend1
networks:
backend1:
nginx-proxy_reverse-proxy:
external: true
# service2/docker-compose.yml
version: "3.3"
services:
php2:
...
networks:
- backend2
apache2:
...
networks:
- nginx-proxy_reverse-proxy
- backend2
environment:
- VIRTUAL_HOST=anothertest.com
mysql2:
...
networks:
- backend2
networks:
backend2:
nginx-proxy_reverse-proxy:
external: true
The reverse-proxy network that is created in nginx-proxy/docker-compose.yml is referred as nginx-proxy_reverse-proxy in the other docker-compose files because whenever you define a network - its final name will be {{folder name}}_{{network name}}
If you want to have a look at a solution that relies on browser proxy extension instead of /etc/hosts, check out mitm-proxy-nginx-companion

reverse proxy docker container to another two docker containers, how to have multiple instances on a single computer

In this project I have an apache docker container (called loadbalancer) which points to either of two apache docker containers. If the path is "/support*" then it goes to the support container otherwise it goes to webapp. Currently to achieve this I have hard coded my docker compose networks subnet and each containers ipv4 address. Then an apache conf file just points to those hard coded ips. This works great for local development environments.
However, it doesn't work for staging servers which need to host multiple instances of the project. I can't spin up more than one instance of this docker-compose network due to the hardcoded subnet/ipv4 addresses. How can I achieve this load balancer setup without hard coding the subnet so I can have multiple instances. Or is there a better solution to achieve the desired effect of many copies being hosted on a single server such as many vhosts in apache container. What would you suggest? As I have no clue as to what would be best practice here.
loadbalancer.conf
<VirtualHost *:80>
TimeOut -1
ProxyPass "/support" "http://172.20.0.5/support"
ProxyPassReverse "/support" "http://172.20.0.5/support"
ProxyPass "/" "http://172.20.0.2/"
ProxyPassReverse "/" "http://172.20.0.2/"
ProxyPreserveHost On
TimeOut -1
</VirtualHost>
docker-compose.yml
version: '3.7'
networks:
pi-net:
ipam:
config:
- subnet: 172.20.0.0/24
services:
cli:
container_name: cli
build: ./docker/cli
networks:
pi-net:
ipv4_address: 172.20.0.3
volumes:
- type: bind
source: .
target: /srv/www
- type: bind
source: $HOME/.gitconfig
target: /home/developer/.gitconfig
extra_hosts:
- "pi.docker:172.20.0.2"
user: developer
stdin_open: true
tty: true
environment:
GIT_PAGER: cat
webapp:
container_name: webapp
build:
context: ./docker/web-server
args:
- vhostsFileName=webapp.conf
networks:
pi-net:
ipv4_address: 172.20.0.2
ports:
- 80
volumes:
- type: bind
source: .
target: /srv/www
# depends on cli because cli entrypoint.sh is creating var/ files needed by httpd
depends_on:
- "cli"
support:
container_name: support
build:
context: ./docker/web-server
args:
- vhostsFileName=support.conf
networks:
pi-net:
ipv4_address: 172.20.0.5
ports:
- 80
volumes:
- type: bind
source: .
target: /srv/www
# depends on cli because cli entrypoint.sh is creating var/ files needed by httpd
depends_on:
- "cli"
loadbalancer:
container_name: loadbalancer
build:
context: ./docker/web-server
args:
- vhostsFileName=loadbalancer.conf
networks:
pi-net:
ipv4_address: 172.20.0.6
ports:
- 80:80
db:
container_name: db
build: ./docker/mysql
networks:
pi-net:
ipv4_address: 172.20.0.4
ports:
- 3306:3306
volumes:
- db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: pi
MYSQL_USER: root
MYSQL_PASSWORD: root
restart: always
volumes:
db:
driver: local
Docker provides an internal DNS service to resolve container names as host names, and Docker Compose provides a network for you. You should make two changes:
In your Apache configuration, replace the explicit IP addresses with the name of the corresponding service block in the docker-compose.yml: http://support/support, for example.
Delete all of the networks: and container_name: settings in the docker-compose.yml, since they're redundant and limit reuse of the file. (Docker will assign IP addresses for you and Docker Compose will pick container names, but there's nothing wrong with these defaults.)
(Many questions of this form also use the outdated links: functionality; it's safe to delete all of the links: blocks too.)