Reputation: 11
I will try to explain my situation but I apologize right now because I started studying the subject a little while ago and maybe I don't know how to give all the details correctly.
I recently got a script (backend and two Android apps) that works perfectly on http, but the apps have a payment gateway that works only with https. The author of the code created a doc that teaches you how to install the backend on the server in an automated way, just install Docker and run the backend with the link wget http://authorsite/docker-compose.yaml && docker-compose up -d
.
The installation created the containers for the database and the backend files, and created a docker-compose.yaml file:
version: '3'
services:
mysql:
image: mysql
command: --default-authentication-plugin=mysql_native_password
volumes:
- mysqlvol:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: defaultpassword
redis:
image: redis
volumes:
- redisvol:/data
taxi:
image: author/taxi
restart: always
depends_on:
- "redis"
- "mysql"
volumes:
- ./img:/app/public/img
- ./config:/app/config
- taxiassets:/app/public/assets
links:
- mysql
- redis
ports:
- "8080:8080"
volumes:
redisvol:
mysqlvol:
taxiassets:
The backend page started working at http://example.com:8080
and I just needed to add the same url in the apps, in the config.kt file:
class Config {
companion object {
const val Backend = "http://example.com:8080/"
}
}
Everything works fine, but as I mentioned, I need https for the payment gateway to work in apps, and also to get rid of http. The author does not give this information, so I researched and found some tutorials on reverse proxy, I already had Apache installed on my server (outside of Docker) and followed the tutorials related to Apache.
My .conf file (with Let's Encrypt) looked like this:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName example.com
ServerAlias www.example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ProxyPreserveHost On
ProxyPassReverseCookiePath / /
<Proxy *>
Order deny,allow
Allow from all
Allow from localhost
</Proxy>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
</IfModule>
<IfModule mod_ssl.c>
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName example.com
ServerAlias www.example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyPass / ws://127.0.0.1:8080/
</VirtualHost>
</IfModule>
I'm still learning and I sure must be doing something wrong, the backend still works at http://example.com:8080
but it doesn't work at https://example.com:8080
, but even so the backend has now started work correctly at https://example.com
. I can access the panel with https, but when trying to open apps with https://example.com
, as in the example:
class Config {
companion object {
const val Backend = "https://example.com/"
}
}
Or
class Config {
companion object {
const val Backend = "https://example.com:8080/"
}
}
the apps started to show connection error and are not working properly.
I don't know if this is the correct approach, the backend works with the changes mentioned, before it was http://example.com:8080
and now I can access it at https://example.com
, but this new url makes apps don't work the same way and have connection errors. If I keep the original url:
class Config {
companion object {
const val Backend = "http://example.com:8080/"
}
}
Apps are back to working normally.
What am I doing wrong?
Upvotes: 1
Views: 581
Reputation: 14753
Replying to your question would be two-fold:
You might want to dockerize your TLS reverse proxy, which would increase maintainability easiness (no need for some manual installation/configuration outside of Docker), and isolation w.r.t. your host machine; see e.g. that other SO question for pointers.
In your docker-compose.yml, when adding an extra service (dockerized TLS termination proxy), named e.g. proxy
, in charge of handling the inbound requests on your host, you should address the following things:
Expose the 80
and 443
ports for this service:
services:
proxy:
image: …
ports:
- '80:80'
- '443:443'
…
Note: it is typical to also include the standard HTTP port 80, in order to implement a permanent redirection (HTTP 301) to HTTPS.
Remove the ports: ["8080:8080"]
specification from your taxi
service (otherwise http://example.com:8080
will still be accessible).
Don't use the links:
property as it is a deprecated feature.
Instead, put the various containers that have to communicate each other in the same custom network:
networks:
- network-name
in docker-compose services (taxi
, mysql
, redis
), instead of
links:
- mysql
- redis
networks:
network-name:
driver: bridge
at the end of your docker-compose.yml.Specify URLs such as http://mysql:3306
or http://redis:6379
within the taxi
service.
Ideally, these URL should be set as docker-compose environment variables of your taxi
service.
Similarly, specify the URL http://taxi:8080
in your proxy
service (similarly to the last code snippet you mentioned in your question, which would then be const val Backend = "http://taxi:8080/"
) to access the taxi
service from proxy
.
To this aim, you may also want to create yet another custom docker-compose network, common to (proxy
, taxi
) services.
Note that the URLs above start with http:
, not https:
, given they correspond to internal HTTP requests between containers, and the domain name in these URL is the docker-compose service name.
For more details on these docker-compose networking notions, see the official doc.
Finally, here is a sample component diagram that summarizes the various containers involved in the application you consider:
Upvotes: 1