Here's the secret to stuff like this:
Run a single reverse proxy / edge router for all of your containerised services.
I recommend Traefik - https://gitlab.com/Matt.Jolly/traefik-grafana-prometheus-docker
You can configure services with labels attached to the container and (almost) never expose ports directly. It also lets you host an arbitrary number of services listening on 80/443.
An example config might look like this:
# docker-compose.yml
version: '3.9'
services:
bitwarden:
image: vaultwarden/server:latest
restart: always
volumes:
- /data/vaultwarden/:/data
environment:
# - ADMIN_TOKEN=
- WEBSOCKET_ENABLED=true
networks:
- proxy
labels:
- traefik.enable=true
- traefik.http.routers.bitwarden-ui-https.tls.certresolver=letsencrypt
- traefik.http.middlewares.redirect-https.redirectScheme.scheme=https
- traefik.http.middlewares.redirect-https.redirectScheme.permanent=true
- traefik.http.routers.bitwarden-ui-https.rule=Host(`my.domain.com`)
- traefik.http.routers.bitwarden-ui-https.entrypoints=websecure
- traefik.http.routers.bitwarden-ui-https.tls=true
- traefik.http.routers.bitwarden-ui-https.service=bitwarden-ui
- traefik.http.routers.bitwarden-ui-http.rule=Host(`my.domain.com`)
- traefik.http.routers.bitwarden-ui-http.entrypoints=web
- traefik.http.routers.bitwarden-ui-http.middlewares=redirect-https
- traefik.http.routers.bitwarden-ui-http.service=bitwarden-ui
- traefik.http.services.bitwarden-ui.loadbalancer.server.port=80
- traefik.http.routers.bitwarden-websocket-https.rule=Host(`my.domain.com) && Path(`/notifications/hub`)
- traefik.http.routers.bitwarden-websocket-https.entrypoints=websecure
- traefik.http.routers.bitwarden-websocket-https.tls=true
- traefik.http.routers.bitwarden-websocket-https.service=bitwarden-websocket
- traefik.http.routers.bitwarden-websocket-http.rule=Host(`my.domain.com`) && Path(`/notifications/hub`)
- traefik.http.routers.bitwarden-websocket-http.entrypoints=web
- traefik.http.routers.bitwarden-websocket-http.middlewares=redirect-https
- traefik.http.routers.bitwarden-websocket-http.service=bitwarden-websocket
- traefik.http.services.bitwarden-websocket.loadbalancer.server.port=3012