Not resolving port 80 (http-portal container)

We have been trying to deploy Self-hosted Retool on Azure Virtual Machine with Docker Compose but have been having issues.

We have been following the tutorial: Deploy Self-hosted Retool on Azure Virtual Machines | Retool Docs

We have not configured SSL as yet, just testing using HTTP.

All containers are up and running and my understanding is the api container container is exposed on port 3000 and the http-portal container is exposed on ports 80 and 443.

We’ve tried to running commands for curl to test port forwarding but seems like port 80 is not working. Port 3000 works fine bringing up the Retool auth signup page.

Example curl commands run with result recorded on Notepad:
image

Docker-compose.yml file:

# Use as is if using self-managed Temporal cluster deployed alongside Retool
# Compare other deployment options here: https://docs.retool/self-hosted/concepts/temporal#compare-options
version: "2"
services:
api:
build:
context: ./
dockerfile: Dockerfile
env_file: ./docker.env
environment:
- DEPLOYMENT_TEMPLATE_TYPE=docker-compose
- SERVICE_TYPE=MAIN_BACKEND,DB_CONNECTOR,DB_SSH_CONNECTOR
- DBCONNECTOR_POSTGRES_POOL_MAX_SIZE=100
- DBCONNECTOR_QUERY_TIMEOUT_MS=120000
- WORKFLOW_BACKEND_HOST=http://workflows-backend:3000
- WORKFLOW_TEMPORAL_CLUSTER_FRONTEND_HOST=temporal
- WORKFLOW_TEMPORAL_CLUSTER_FRONTEND_PORT=7233
- CODE_EXECUTOR_INGRESS_DOMAIN=http://code-executor:3004
networks:
- frontend-network
- backend-network
- temporal-network
- code-executor-network
depends_on:
- postgres
- retooldb-postgres
- jobs-runner
- workflows-worker
- code-executor
command: bash -c "./docker_scripts/wait-for-it.sh postgres:5432; ./docker_scripts/start_api.sh"
links:
- postgres
ports:
- "3000:3000"
restart: on-failure
volumes:
- ./keys:/root/.ssh
- ./keys:/retool_backend/keys
- ssh:/retool_backend/autogen_ssh_keys
- ./retool:/usr/local/retool-git-repo
- ${BOOTSTRAP_SOURCE:-./retool}:/usr/local/retool-repo

jobs-runner:
build:
context: ./
dockerfile: Dockerfile
env_file: ./docker.env
environment:
- DEPLOYMENT_TEMPLATE_TYPE=docker-compose
- SERVICE_TYPE=JOBS_RUNNER
networks:
- backend-network
depends_on:
- postgres
command: bash -c "chmod -R +x ./docker_scripts; sync; ./docker_scripts/wait-for-it.sh postgres:5432; ./docker_scripts/start_api.sh"
links:
- postgres
volumes:
- ./keys:/root/.ssh

workflows-worker:
build:
context: ./
dockerfile: Dockerfile
command: bash -c "./docker_scripts/wait-for-it.sh postgres:5432; ./docker_scripts/start_api.sh"
env_file: ./docker.env
depends_on:
- temporal
environment:
- DEPLOYMENT_TEMPLATE_TYPE=docker-compose
- SERVICE_TYPE=WORKFLOW_TEMPORAL_WORKER
- DISABLE_DATABASE_MIGRATIONS=true
- WORKFLOW_BACKEND_HOST=http://workflows-backend:3000
- WORKFLOW_TEMPORAL_CLUSTER_FRONTEND_HOST=temporal
- WORKFLOW_TEMPORAL_CLUSTER_FRONTEND_PORT=7233
- CODE_EXECUTOR_INGRESS_DOMAIN=http://code-executor:3004
networks:
- backend-network
- temporal-network
- code-executor-network
restart: on-failure

workflows-backend:
build:
context: ./
dockerfile: Dockerfile
env_file: ./docker.env
environment:
- DEPLOYMENT_TEMPLATE_TYPE=docker-compose
- SERVICE_TYPE=WORKFLOW_BACKEND,DB_CONNECTOR,DB_SSH_CONNECTOR
- WORKFLOW_BACKEND_HOST=http://workflows-backend:3000
- WORKFLOW_TEMPORAL_CLUSTER_FRONTEND_HOST=temporal
- WORKFLOW_TEMPORAL_CLUSTER_FRONTEND_PORT=7233
- CODE_EXECUTOR_INGRESS_DOMAIN=http://code-executor:3004
networks:
- backend-network
- temporal-network
- code-executor-network
depends_on:
- postgres
- retooldb-postgres
- code-executor
command: bash -c "./docker_scripts/wait-for-it.sh postgres:5432; ./docker_scripts/start_api.sh"
links:
- postgres
restart: on-failure
volumes:
- ./keys:/root/.ssh
- ./keys:/retool_backend/keys
- ssh:/retool_backend/autogen_ssh_keys
- ./retool:/usr/local/retool-git-repo
- ${BOOTSTRAP_SOURCE:-./retool}:/usr/local/retool-repo

code-executor:
build:
context: ./
dockerfile: CodeExecutor.Dockerfile
command: bash -c "./start.sh"
env_file: ./docker.env
environment:
- DEPLOYMENT_TEMPLATE_TYPE=docker-compose
- NODE_OPTIONS=--max_old_space_size=1024
networks:
- code-executor-network
# code-executor uses nsjail to sandbox code execution. nsjail requires
# privileged container access.
# If your deployment does not support privileged access, you can set this
# to false to not use nsjail. Without nsjail, all code is run without
# sandboxing within your deployment.
privileged: true
restart: on-failure

# Retool's storage database. See these docs to migrate to an externally hosted database: Self-hosted Retool quickstart | Retool Docs
postgres:
image: "postgres:11.13"
env_file: docker.env
networks:
- backend-network
- intra-temporal-network
volumes:
- data:/var/lib/postgresql/data

retooldb-postgres:
image: "postgres:14.3"
env_file: retooldb.env
networks:
- backend-network
volumes:
- retooldb-data:/var/lib/postgresql/data

# Not required, but leave this container to use nginx for handling the frontend & SSL certification
https-portal:
image: tryretool/https-portal:latest
ports:
- "80:80"
- "443:443"
links:
- api
restart: always
env_file: ./docker.env
environment:
STAGE: "local" # <- Change 'local' to 'production' to use a LetsEncrypt signed SSL cert
CLIENT_MAX_BODY_SIZE: 40M
KEEPALIVE_TIMEOUT: 605
PROXY_CONNECT_TIMEOUT: 600
PROXY_SEND_TIMEOUT: 600
PROXY_READ_TIMEOUT: 600
networks:
- frontend-network

temporal:
container_name: temporal
env_file: ./docker.env
environment:
- DB=postgresql
- DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml
# To enable TLS between temporal and external postgres, set both below variables to true
- SQL_TLS_ENABLED=false
- SQL_TLS=false
# Defined twice because temporal-server and temporal-sql-tool use different envvars
- SQL_TLS_DISABLE_HOST_VERIFICATION=true
- SQL_HOST_VERIFICATION=false
image: tryretool/one-offs:retool-temporal-1.1.2
networks:
- intra-temporal-network
- temporal-network
ports:
- "127.0.0.1:7233:7233"
volumes:
- ./dynamicconfig:/etc/temporal/config/dynamicconfig
temporal-admin-tools:
container_name: temporal-admin-tools
depends_on:
- temporal
environment:
- TEMPORAL_CLI_ADDRESS=temporal:7233
image: temporalio/admin-tools:1.18.5
networks:
- intra-temporal-network
stdin_open: true
tty: true
temporal-ui:
container_name: temporal-ui
depends_on:
- temporal
environment:
- TEMPORAL_ADDRESS=temporal:7233
- TEMPORAL_CORS_ORIGINS=http://localhost:3000
image: temporalio/ui:2.9.1
networks:
- intra-temporal-network
ports:
- "8080:8080"

networks:
frontend-network:
backend-network:
code-executor-network:
temporal-network:
intra-temporal-network:

volumes:
ssh:
data:
retooldb-data:

docker-compose ps command result:

One thing wanted to note was the docker.env file due to some of the passwords and encryption key having special characters we has to add double quotes. But doing do, we had an error with the communications error (line 26-53)

Error:
line 27: unexpected character """ in variable name "";; communications error to 208.67.222.222#53: timed out"

So we commented out the line 26-35 (communications error) which then successfully allowed us for command sudo docker-compose up -d to successfully run.


continuous:
image

I've done the checks on Nginx and it is all pointing to Nginx running fine so I think this current issue is related to Retool?
Any guidance would be greatly appreciated.

1 Like

Hi @dtpuser! Welcome to the community. :wave:

In this case, I don't necessarily expect https-portal to forward the request to the api container, given that you haven't yet configured SSL for your instance. As a service, https-portal is built on top of nginx but isn't meant to function as a typical reverse proxy. It's primary purpose is to provision a self-signed certificate and handle all subsequent SSL traffic. In fact, the only reason we realistically open up port 80 is to complete Let's Encrypt's HTTP challenge.

I think you should be fine to move on with setting up a domain and configuring SSL, but want to first clarify the communications error that you're seeing. The script that generates the docker.env file makes a call to myip.opendns.com in order to fetch your public IP address, but it looks like that was blocked by a firewall or something similar. That whole block should look something like the below, except with a real IP address:

# Change '123.0.45.678' to retool.yourcompany.com to set up SSL properly
DOMAINS=123.0.45.678 -> http://api:3000

Let me know if you run into any additional issues or just have follow-up questions.