I've just spent the last few hours banging my head against a wall trying to figure out why Docker and Traefik wouldn't play ball, and allow me to connect to my SFTP container on port 22.
I'd tried opening the firewall, checking all the traefik config, checking the docker network, inspecting the logs, updating the labels on the container etc etc etc.
Finally, I realised it was a simple YAML error, let's take a look at the config:
version: '3.3'
services:
traefik:
image: traefik:latest
restart: always
labels:
traefik.enable: false
ports:
- 22:22
- 80:80
- 443:443
Looks simple enough, and I've never had any issues with the HTTP and HTTPS services I've been running for months. Because I was doing TCP routing, rather than HTTP, I was sure I had an issue with my Traefik configuration, until I realised, YAML supports "Sexagesimals".
Sexagesimal (also known as base 60 or sexagenary) is a numeral system with sixty as its base.
In version 1.1 of the YAML data storage format, sexagesimals are supported for plain scalars, and formally specified both for integers and floating point numbers. This has led to confusion, as e.g. some MAC addresses would be recognised as sexagesimals and loaded as integers, where others were not and loaded as strings. In YAML 1.2 support for sexagesimals was dropped. https://en.wikipedia.org/wiki/Sexagesimal#YAML
Running docker-compose ps
shows how this has been parsed:
Name Command State Ports
----------------------------------------------------------------------------------------------------------------------
traefik_traefik_1 /entrypoint.sh traefik Up 0.0.0.0:32768->1342/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
(Note the 0.0.0.0:32768->1342/tcp
bit).
Simply wrapping the port numbers in quotes forces YAML to parse this normally, without converting to a base 60 number, and fixing the issue:
ports:
- "22:22"
- "80:80"
- "443:443"
Name Command State Ports
-----------------------------------------------------------------------------------------------------------------
traefik_traefik_1 /entrypoint.sh traefik Up 0.0.0.0:22->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
So, lesson learnt, always wrap Docker ports (or any numbers with colons) in quotes to avoid headaches in future.