Docker port mapping and redirects
TIL: If you’re doing server-side redirects in a Docker container, you have to be a little careful with the port mapping.
These days, I mostly do local development of web sites with Docker containers.
I spin up a little cluster with docker compose
that includes an nginx
container for the web server and maybe containers for other servers.
Typically, I just let the nginx
server run on port 80 and map it to
something else on my laptop:
nginx:
image: nginx:1.23.3
container_name: nginx
ports:
- 8385:80
volumes:
- ../build/website:/usr/share/nginx/html
- ../build/cache:/var/cache/nginx
- ../build/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
stdin_open: true
tty: true
networks:
- external_net
When that container is running, localhost:8385
on my laptop is
nginx
on port 80.
For one particular container, I got very odd behavior: sometimes
following a link would lose the port number. I’d click in a link to
http://localhost:8385/path
and the browser would complain that
http://localhost/path/
wasn’t found. I assumed this was just browser
caching or something until I saw the same thing in a link checking script.
Once I knew it wasn’t just some weirdness in the browser, it didn’t
take long to track down. If you’re observant, there’s a clue in the previous
paragraph. The attempt to read /path
, the name of a directory, is redirected
on the server side to /path/
but because the server thinks it’s running in
port 80, that’s http://localhost/path/
.
There’s nothing profound here, and the fix is simply to run nginx
in
the container on port 8385 as well. Problem solved. Well, mostly. The browser
is still acting a bit funny sometimes, but I really think that’s
just some caching artifact or something now.