To better support local development, DevCom provides a few services and tools.
A global name that resolves locally
Often, when working locally, we need to use a hostname that is not localhost. To support these use cases, *.localhost.devcom.vt.edu
has been configured to resolve locally, for both IPv4 and IPv6. You are welcome to use these names for any local development.
> dig localhost.devcom.vt.edu
;; ANSWER SECTION:
localhost.devcom.vt.edu. 86400 IN A 127.0.0.1
> dig anything.localhost.devcom.vt.edu
;; ANSWER SECTION:
anything.localhost.devcom.vt.edu. 86400 IN A 127.0.0.1
> dig localhost.devcom.vt.edu AAAA
;; ANSWER SECTION:
localhost.devcom.vt.edu. 86400 IN AAAA ::1
> dig anything.localhost.devcom.vt.edu AAAA
;; ANSWER SECTION:
anything.localhost.devcom.vt.edu. 86400 IN AAAA ::1
Why use these names?
Great question! There are several reasons, but here are a few to highlight:
- Automatic VT Login support - if your app needs to authenticate users using VT Login, no registration is required as all *.vt.edu services are automatically authorized.
- No need for custom
/etc/hosts
entries - many teams/developers create their own names and point them locally using custom host records. Now, no more machine-specific config is needed! - No need for a custom name and static IP (for dev) - a few developers had their own DNS name with a static IP associated with it. While this works, it also requires the ability to get that static IP, which is impossible when working remotely or using another machine. Granted, this does make it easier to support remote login or to let someone quickly check out something you’re working on.
- A single name the entire team can share - using these names, you can easily create a project README with links that will work for everyone on the team
Signed/Trusted Certs for Local Development
The devcom/devcom-localhost-proxy repo contains a /cert
directory that has a signed/trusted cert issued by LetsEncrypt for the *.localhost.devcom.vt.edu
names.
Note: in most cases, you will want to use a localhost proxy, rather than using the cert directly. But, it’s available if you need it.
Certificate Usage
This certificate should be used only for local development and not bundled in any application that is deployed or installed. Read more about localhost certs here.
Why use HTTPS during local development?
Beyond simply saying “use HTTPS everywhere”, there are a few specific reasons to use HTTPS during local development:
- Some libraries will require it - as an example, if you run a mock CAS server (details below), it must be behind HTTPS because all CAS client libraries require a HTTPS connection when validating the CAS ticket. While you can use a self-signed cert, you would then have to configure the CAS library with the CA or tell it to ignore the certificate (not recommended)
- It more closely aligns with production - most of our prod environments have load balancers or other reverse proxies sitting in front of our apps, who are performing TLS termination. But doing this locally (possibly by a proxy below), we can validate our apps are configured to require a TLS connection, use the correct headers for redirects, etc.
Localhost Proxies
To enable the easier usage of the TLS certificates, we additionally provide container images that are already configured to use the certs. By simply starting the container, you can have a smart proxy ready to send traffic to other containers. This is a simple wrapper around Traefik, so will listen for other containers.
A quick Docker example
After running the following command, you will have the proxy up and running on your machine! We mount the Docker socket in so Traefik can watch for container events and update its routing configuration accordingly.
docker run -d \
-p 80:80 -p 443:443 \
-v /var/run/docker.sock:/var/run/docker.sock
dtr.it.vt.edu/devcom/devcom-localhost-proxy:traefik-2.3
Now, we can start another app behind the proxy. While this is a static website, it could be any other container of your choice, including a development container!
docker run -d \
--label 'traefik.http.routers.app.rule=Host(`app.localhost.devcom.vt.edu`)' \
nginx:alpine
With this command, you should be able to open https://app.localhost.devcom.vt.edu and see the nginx welcome page! How? What happened? Here’s what happened…
- When the container nginx started, Traefik (the proxy) saw the container start, looked at its labels, and updated its configuration to send requests with a hostname of
app.localhost.devcom.vt.edu
to the container. - When the browser opened
app.localhost.devcom.vt.edu
, it connected to port 443 on the local machine, which is the proxy. - The proxy received the request and used its configuration to find the correct target. The nginx container was chosen, so forwarded the request to it.
Labels to Know
While you can specify many configuration points using Docker labels, the following are going to be the most important to know:
traefik.http.routers.<app-name>.rule
- the routing rule that must be satisfied in order for traffic to be sent to this container. To view all supported rules, head to the Traefik router rules documentationtraefik.http.services.<app-name>.loadbalancer.server.port
- the container port that the proxy should send traffic to. This defaults to 80 if not defined.