Summary: 2 separate applications, both using docker-compose, how can I have http://app-1.test and http://app-2.test available at the same time?
Description:
I feel like I've missed something super-simple. I have 2 php-fpm (via nginx) applications, both run by similar docker-compose setups, somewhat like:
# docker-compose.yaml
version: '3'
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: app_1
tty: true
depends_on:
- db
- dbtest
working_dir: /var/www
volumes:
- ./:/var/www
webserver:
image: nginx:stable
container_name: app_1_webserver
restart: always
ports:
- "80:80"
depends_on:
- app
volumes:
- ./:/var/www
- ./docker/app.conf:/etc/nginx/conf.d/default.conf
links:
- app
# ...
On my /etc/hosts, I can add something like
127.0.0.1 app-1.test
Now I can call the app via the browser by going to app-1.test.
The second one has a similar setup, but of course it won't go up, because port 80 is blocked. I can of course change the port, but then the url would be something like app-2.test:81 instead of app-2.test. What can I do, so I can run a second application under a different local hostname? Or is using a different port the best way to go?
You can't. What you can do is add a "router" in front of your images (a third image) which does routing (proxy passing) based on the host name.
Apache or Nginx are often used for these kinds of things.
e.g. with apache server
https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
<VirtualHost *:80>
ServerName app-1.test
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://image1:80/
ProxyPassReverse / http://image1:80/
ErrorLog /var/log/apache2/error.log
LogLevel info
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName app-2.test
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://image2:80/
ProxyPassReverse / http://image2:80/
ErrorLog /var/log/apache2/error.log
LogLevel info
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
now you can add both names on the same ip in your /etc/hosts file and the server can route internally based on the provided hostname (ServerName).
The http://image1:80/ (and its like) references should be changed to the docker internal dns like specified in the docker-compose.yml
Related
I want to use Varnish above the openmaptiles and my SSL apache2 server, so I change the docker-compose.yml like that
version: "3"
volumes:
pgdata:
networks:
postgres:
driver: bridge
services:
postgres:
image: "${POSTGIS_IMAGE:-openmaptiles/postgis}:${TOOLS_VERSION}"
# Use "command: postgres -c jit=off" for PostgreSQL 11+ because of slow large MVT query processing
# Use "shm_size: 512m" if you want to prevent a possible 'No space left on device' during 'make generate-tiles-pg'
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- postgres
ports:
- "${PGPORT:-5432}:${PGPORT:-5432}"
env_file: .env
environment:
# postgress container uses old variable names
POSTGRES_DB: ${PGDATABASE:-openmaptiles}
POSTGRES_USER: ${PGUSER:-openmaptiles}
POSTGRES_PASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
import-data:
image: "openmaptiles/import-data:${TOOLS_VERSION}"
env_file: .env
networks:
- postgres
openmaptiles-tools: &openmaptiles-tools
image: "openmaptiles/openmaptiles-tools:${TOOLS_VERSION}"
env_file: .env
environment:
# Must match the version of this file (first line)
# download-osm will use it when generating a composer file
MAKE_DC_VERSION: "3"
# Allow DIFF_MODE, MIN_ZOOM, and MAX_ZOOM to be overwritten from shell
DIFF_MODE: ${DIFF_MODE}
MIN_ZOOM: ${MIN_ZOOM}
MAX_ZOOM: ${MAX_ZOOM}
#Provide BBOX from *.bbox file if exists, else from .env
BBOX: ${BBOX}
# Imposm configuration file describes how to load updates when enabled
IMPOSM_CONFIG_FILE: ${IMPOSM_CONFIG_FILE}
# Control import-sql processes
MAX_PARALLEL_PSQL: ${MAX_PARALLEL_PSQL}
PGDATABASE: ${PGDATABASE:-openmaptiles}
PGUSER: ${PGUSER:-openmaptiles}
PGPASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
MBTILES_FILE: ${MBTILES_FILE}
networks:
- postgres
volumes:
- .:/tileset
- ./data:/import
- ./data:/export
- ./build/sql:/sql
- ./build:/mapping
- ./cache:/cache
- ./style:/style
update-osm:
<<: *openmaptiles-tools
command: import-update
generate-changed-vectortiles:
image: "openmaptiles/generate-vectortiles:${TOOLS_VERSION}"
command: ./export-list.sh
volumes:
- ./data:/export
- ./build/openmaptiles.tm2source:/tm2source
networks:
- postgres
env_file: .env
environment:
MBTILES_NAME: ${MBTILES_FILE}
# Control tilelive-copy threads
COPY_CONCURRENCY: ${COPY_CONCURRENCY}
PGDATABASE: ${PGDATABASE:-openmaptiles}
PGUSER: ${PGUSER:-openmaptiles}
PGPASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
generate-vectortiles:
image: "openmaptiles/generate-vectortiles:${TOOLS_VERSION}"
volumes:
- ./data:/export
- ./build/openmaptiles.tm2source:/tm2source
networks:
- postgres
env_file: .env
environment:
MBTILES_NAME: ${MBTILES_FILE}
BBOX: ${BBOX}
MIN_ZOOM: ${MIN_ZOOM}
MAX_ZOOM: ${MAX_ZOOM}
# Control tilelive-copy threads
COPY_CONCURRENCY: ${COPY_CONCURRENCY}
#
PGDATABASE: ${PGDATABASE:-openmaptiles}
PGUSER: ${PGUSER:-openmaptiles}
PGPASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
postserve:
image: "openmaptiles/openmaptiles-tools:${TOOLS_VERSION}"
command: "postserve ${TILESET_FILE} --verbose --serve=${OMT_HOST:-http://localhost}:${PPORT:-8090}"
env_file: .env
environment:
TILESET_FILE: ${TILESET_FILE}
networks:
- postgres
#ports:
# - "${PPORT:-8090}:${PPORT:-8090}"
volumes:
- .:/tileset
varnish:
image: eeacms/varnish
ports:
- "6081:6081"
depends_on:
- postserve
networks:
- postgres
environment:
BACKENDS: "postserve"
BACKENDS_PORT: "8090"
BACKENDS_PROBE_INTERVAL: "60s"
BACKENDS_PROBE_TIMEOUT: "10s"
BACKENDS_PROBE_URL: "/data/openmaptiles/0/0/0.pbf"
#DNS_ENABLED: "true"
maputnik_editor:
image: "maputnik/editor"
ports:
- "8088:8888"
tileserver-gl:
image: "maptiler/tileserver-gl:latest"
command:
- --port
- "${TPORT:-8080}"
- --config
- "/style/config.json"
ports:
- "${TPORT:-8080}:${TPORT:-8080}"
depends_on:
- varnish
volumes:
- ./data:/data
- ./style:/style
- ./build:/build
And change my apache config to use the varnish port in the proxypass and proxyreverse:
<VirtualHost *:80>
ServerName tiles.example.com
Protocols h2 h2c http/1.1
ErrorDocument 404 /404.html
# disable proxy for the /font-family sub-directory
# must be placed on top of the other ProxyPass directive
ProxyPass /font-family !
Alias "/font-family" "/var/www/font-family"
#HTTP proxy
ProxyPass / http://localhost:6081/
ProxyPassReverse / http://localhost:6081/
ProxyPreserveHost On
ErrorLog ${APACHE_LOG_DIR}/tileserver-gl.error.log
CustomLog ${APACHE_LOG_DIR}/tileserver-gl.access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =tiles.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)
<VirtualHost *:443>
ServerName tiles.example.com
Protocols h2 h2c http/1.1
ErrorDocument 404 /404.html
# disable proxy for the /font-family sub-directory
# must be placed on top of the other ProxyPass directive
ProxyPass /font-family !
Alias "/font-family" "/var/www/font-family"
#HTTP proxy
ProxyPass / http://localhost:6081/
ProxyPassReverse / http://localhost:6081/
ProxyPreserveHost On
ErrorLog ${APACHE_LOG_DIR}/tileserver-gl.error.log
CustomLog ${APACHE_LOG_DIR}/tileserver-gl.access.log combined
SSLCertificateFile /etc/letsencrypt/live/tiles.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/tiles.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
Header always set Strict-Transport-Security "max-age=31536000"
SSLUseStapling on
Header always set Content-Security-Policy upgrade-insecure-requests
RequestHeader set X-Forwarded-Host "tiles.example.com"
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
</IfModule>
Then rerun docker-compose up -d
But when I access the tiles I've got a 503 error
503 Backend fetch failed
Any idea where is the error in configuration?
Thanks
Based on https://github.com/openmaptiles/openmaptiles-tools and https://hub.docker.com/r/openmaptiles/openmaptiles-tools it doesn't seem like your postserve container that runs the openmaptiles/openmaptiles-tools image actually exposes any network ports for Varnish to connect to.
And while you are specifying a --serve parameter to this container, the Dockerfile for this image doesn't have an EXPOSE definition that opens up any ports.
Maybe you should mount the generated tiles into a web server using volumes and then connect Varnish to that web server.
Please use the official Varnish Docker image that is available on the Docker hub. This image is supported by Varnish Software and receives regular updates. See https://www.varnish-software.com/developers/tutorials/running-varnish-docker for a tutorial on how to use it.
I got two apache containers connect to the same bridge network. First apache 172.20.10.2 and port 8080 (internally 80) Second apache 172.20.10.6 and port 9999 (internaly 80).
First apache is configured with two virtual hosts on port 80.
First vhost support mydomain.com on that apache and everything works correctly.
Second vhost support subdomain.mydomain.com and redirect to second apache server.
This redirects don't work and on logs I got that error:
"GET /favicon.ico HTTP/1.1" 502 360
[proxy:error] [pid 43:tid 3028272160] (111)Connection refused: AH00957: http: attempt to connect to 172.20.10.6:9999 (172.20.10.6) failed
[proxy_http:error] [pid 43:tid 3028272160] [client Client_IP:PORT] AH01114: HTTP: failed to make connection to backend: 172.20.10.6
"GET / HTTP/1.1" 503 299
[proxy:error] [pid 8:tid 3011486752] [client Client_IP:PORT] AH00898: DNS lookup failure for: 172.20.10.6:9999favicon.ico returned by /favicon.ico, referer: http://subdomain.mydomain.com/
"GET /favicon.ico HTTP/1.1" 502 360
docker-compose.yml
version: "3.8"
volumes:
httpd_all:
httpd_all_2:
networks:
frontend_web:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.10.0/29
services:
httpd:
container_name: httpd
image: httpd:latest
hostname:
srv_www01
ports:
- 8080:80/tcp
- 8043:443/tcp
volumes:
- httpd_all:/usr/local/apache2/
networks:
frontend_web:
ipv4_address: 172.20.10.2
restart: unless-stopped
httpd_2:
container_name: httpd_2
image: httpd:latest
hostname:
srv_www02
ports:
- 9999:80/tcp
- 9998:443/tcp
volumes:
- httpd_all_2:/usr/local/apache2/
networks:
frontend_web:
ipv4_address: 172.20.10.6
restart: unless-stopped
vhosts on first apache 172.20.10.2
<VirtualHost *:80>
ServerName mydomain.com
ServerAlias mydomain.com
DocumentRoot /usr/local/apache2/htdocs
Alias /jasno "/usr/local/apache2/htdocs"
</VirtualHost>
<VirtualHost *:80>
ServerName subdomain.mydomain.com
ServerAlias www.subdomain.mydomain.com
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
ProxyPass "/" "http://172.20.10.6:9999"
ProxyPassReverse "/" "http://172.20.10.4:9999"
</VirtualHost>
Connections between containers ignore ports:. If the process inside the second container listens on ports 80 and 443, connections between containers will only ever use those ports, even if ports: make them visible as something else outside the host. Since port 80 is the default HTTP port, you can leave it out of your configuration entirely:
ProxyPass "/" "http://172.20.10.6"
You can simplify this setup even further. As described in Networking in Compose in the Docker documentation, Docker provides an internal DNS system, and each container is accessible from other containers in the same Compose file using its Compose service name. Instead of manually specifying the IP address, you can use that host name in the Apache setup
ProxyPass "/" "http://httpd_2"
Once you've done that, you can simplify the Compose setup considerably. It's almost always safe to let Docker pick IP addresses on its own, rather than assigning them manually. Compose can also assign container names, it creates a network named default for you, and the hostname: setting usually has no visible effect. You should be able to trim this down to:
version: "3.8"
volumes:
httpd_all:
httpd_all_2:
services:
httpd:
image: httpd:latest
ports:
- 8080:80/tcp
- 8043:443/tcp
volumes:
- httpd_all:/usr/local/apache2/
restart: unless-stopped
httpd_2:
image: httpd:latest
# ports: only if the service needs to be
# - 9999:80/tcp accessed from outside Docker; not used
# - 9998:443/tcp for connections between containers
volumes:
- httpd_all_2:/usr/local/apache2/
restart: unless-stopped
Hi all and thanks for assistance
I want add virtual host to my apache server in docker but can not figure it out in the right way and does not work.
Do you know why ?
I'm using windows 10 operating system and webdevops docker image for php-apache.
my docker-compose.yml
www:
depends_on:
- mysql
- mail
image: webdevops/php-apache:7.4
volumes:
- "./www:/var/www/html"
- "./apache/vhost.conf:/opt/docker/etc/httpd/vhost.conf"
- "./apache/hosts:/etc/hosts"
environment:
- VIRTUAL_HOST=pharma.test,tests.dev
ports:
- 8080:80
env_file:
- .env
my vhost.conf
<VirtualHost *:80>
ServerName pharma.test
DocumentRoot /var/www/html/pharma/public
Thanks all for your help
I tried to use this set of dockers, but to no avail.
On the internet, I only find use cases with docker: nginx + phpmyadmin (php-fpm)
If someone can help me with this configuration, how can I configure 2 dockers
apache
php-fpm + phpMyAdmin
I tried to use these settings for vhost.conf of apache
PHP_FPM_CONTAINER=myDockerPhpMyAdmin:9000
<FilesMatch \.php$>
SetHandler proxy:fcgi://${PHP_FPM_CONTAINER}
</FilesMatch>
and
PHP_FPM_CONTAINER=myDockerPhpMyAdmin:9000
<IfModule mod_fcgid.c>
Options +ExecCGI
FcgidConnectTimeout 20
AddType application/x-httpd-php .php
AddHandler application/x-httpd-php .php
ProxyPassMatch ^/${PHP_FPM_CONTEXT}/(.*\.php(/.*)?)$ fcgi://${PHP_FPM_CONTAINER}/\$1"
</IfModule>
Similar to what I had here https://github.com/phpmyadmin/docker/issues/350
The main problems I faced with phpmyadmin docker image were:
it seems to be missconfigured and only serve *.php files by default
it serves everything as text/html
My solution was:
For the vhost
<VirtualHost 192.168.1.2:80>
ServerName phpmyadmin.local.lan
ProxyPreserveHost on
RewriteEngine on
RewriteRule ^/$ /index.php [P,QSA,L]
ProxyPass / "fcgi://127.0.0.1:9000/var/www/html/"
ProxyPassReverse / "fcgi://127.0.0.1:9000/var/www/html/"
<LocationMatch "^/.*\.css">
Header set Content-type "text/css"
</LocationMatch>
<LocationMatch "^/.*\.js">
Header set Content-type "text/javascript"
</LocationMatch>
</VirtualHost>
For the docker compose:
version: "3.8"
services:
mariadb:
image: 'mariadb:10.5.13'
restart: always
hostname: 'mariadb'
environment:
MYSQL_ROOT_PASSWORD: 1234
volumes:
- './volumes/mariadb/varlibmysql:/var/lib/mysql'
ports:
- 3306:3306
phpmyadmin:
image: 'phpmyadmin:5.1.1-fpm-alpine'
restart: always
hostname: 'phpmyadmin'
ports:
- 127.0.0.1:9000:9000
volumes:
- './volumes/phpmyadmin/disablesecurity.conf:/usr/local/etc/php-fpm.d/disablesecurity.conf'
environment:
HIDE_PHP_VERSION: "true"
PMA_ARBITRARY: 1
PMA_ABSOLUTE_URI: https://phpmyadmin.local.lan/
depends_on:
- "mariadb"
Where ./volumes/phpmyadmin/disablesecurity.conf is
[www]
security.limit_extensions =
I'm currently configuring my raspberry pi as my personal home server and I want to use docker. I have few different containers :
-Apache/PHP 81:80
-Nextcloud 8080:80
-Minecraft 25565:25565
I already have a dynamic domaim (http://felixbestwaifu.hopto.org)
When I try to access felixbestwaifu.hopto.org:8080, it timeouts :c
My goal
Nextcloud
cloud.hostname.org
or hostname.org/nextcloud
Website
Domain.org
Domain.org/about.php
Domain.org/Anime.php
I tried using NGINX by creating a nextcloud.conf in /sites-enabled/ and /sites-available/, but it didn't work at all ^^'
server {
listen 80;
server_name nextcloud;
location /nextcloud {
proxy_pass 192.168.2.150:8080/;
}
}
Note : 192.168.2.150 is my pi static IP in my network
So here is my question : How do you set-up a reverse proxy for docker containers ?
I would really appreciate your help >//< (sorry for bad English)
Let us suppose your Apache-PHP container is called apache_php. You should have two .conf files there with similar contents (less or more is regarding what you need in your conf files).
/etc/apache2/sites-available/minecraft.conf:
<VirtualHost *:80>
ServerName minecraft.com
ServerAdmin webmaster#minecraft
DocumentRoot /home/minecraft
ProxyPreserveHost On
ProxyPass "/" "http://minecraft:25565/"
ProxyPassReverse "/" "http://minecraft:25565/"
ProxyRequests Off
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
/etc/apache2/sites-available/nextcloud.conf:
<VirtualHost *:80>
ServerName nextcloud.com
ServerAdmin webmaster#nextcloud
DocumentRoot /home/nextcloud
ProxyPreserveHost On
ProxyPass "/" "http://nextcloud:8080/"
ProxyPassReverse "/" "http://nextcloud:8080/"
ProxyRequests Off
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Note the trailing / in ProxyPass and ProxyPassReverse. If you do not add them, final URLs will be something like http://minecraft:25565your_page, while with trailing / it will be http://minecraft:25565/your_page.
In this case if anyone enters minecraft.com, your Apache proxies him to minecraft site and *minecraft is only accessible by your Apache container.
Note that minecraft.com and minecraft are two different websites in a network called proxy that I talk about it below
This is what I do in my container, but let me explain it up to my knowledge:
Suppose Your Apache, your Nextcloud and Minecraft are in the same network (in this case you should create a network, in my case it's called proxy network) and all of these three containers should see each other by pinging.
How your docker-compose.yml file should look like in this case:
version: '3.9'
services:
apache_php:
build: .
restart: always
ports:
- "81:80"
minecraft:
build: .
restart: always
ports:
- "25565:25565"
nextcloud:
build: .
restart: always
ports:
- "8080:80"
networks:
default:
external:
name: proxy
volumes:
db_data: {}
So in this file, I'm creating three images called apache_php, minecraft and nextcloud that is built via Dockerfile via build keyword. I also proxy ports 81 to 80, port 25565 to 25565 and port 8080 to 80.
Then you can create a Dockerfile or modify existing one with similar contents:
FROM your_os_base:tag
COPY minecraft.conf /etc/apache2/sites-available/
COPY nextcloud.conf /etc/apache2/sites-available/
COPY my_bash_commands.sh /root/
RUN chmod +x /root/my_bash_commands.sh
RUN /root/my_bash_commands.sh
ENTRYPOINT ["your_thing"]
Now what is my_bash_commands.sh in my case? As default shell is sh in most cases, I create a bash file so that I get my desired results.
The my_bash_commands.sh is similar to this:
#!/usr/bash
service apache2 start
a2ensite minecraft
a2ensite nextcloud
a2enmod proxy
a2enmod proxy_http
service apache2 restart
Now you can create them by running docker-compose up -d if you are in the path where docker-compose.yml is, else you should use docker-compose -f /absolute_patht_to/docker-compose.yml up -d.