Skip to content

Docker Deployment

envgo deploy generates a starting point for containerised deployment. This page explains what it produces, how to run it, and where you have to fill in the gaps.

Generate the configs

Terminal window
envgo deploy -o ./deploy
Deploy configs generated at: ./deploy
Caddyfile
nginx.conf
Dockerfile

What gets generated

deploy/Dockerfile
FROM alpine:latest
RUN apk --no-cache add caddy
COPY . /var/www/envgo
COPY Caddyfile /etc/caddy/Caddyfile
EXPOSE 80 443
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
deploy/Caddyfile
:443 {
tls /etc/ssl/certs/envgo.crt /etc/ssl/private/envgo.key
root * .
file_server
reverse_proxy /api/* localhost:8080
}
:80 {
redir https://{host}{uri} permanent
}

nginx.conf is a matching nginx server block with the same two listeners and an /api/ proxy pass.

The port mismatch to watch for

The container listens on 80 and 443, because Caddy is the entry point. A docker run -p 8080:8080 mapping therefore exposes a port that nothing inside the container is listening on. Map the ports Caddy actually uses:

Terminal window
docker run -d -p 80:80 -p 443:443 --name envgo envgo

Building a working image

A minimal adaptation that actually runs envGo behind Caddy:

Dockerfile
FROM alpine:latest
RUN apk --no-cache add caddy ca-certificates
# Copy the envGo binary built for linux/amd64 (from the release dist/)
COPY envgo-linux-amd64 /usr/local/bin/envgo
RUN chmod +x /usr/local/bin/envgo
# Your site
COPY site/ /var/www/envgo/
WORKDIR /var/www/envgo
COPY Caddyfile /etc/caddy/Caddyfile
EXPOSE 80 443
# Start envGo, then Caddy in the foreground
CMD ["/bin/sh", "-c", "envgo --config envgo.routes.json --env /etc/envgo/.env --dir /var/www/envgo --host 127.0.0.1 --port 8080 & caddy run --config /etc/caddy/Caddyfile"]
Caddyfile
:80 {
reverse_proxy 127.0.0.1:8080
}

Build and run

Terminal window
cd deploy
docker build -t envgo .
docker run -d -p 80:80 -p 443:443 --name envgo envgo

Verify

Terminal window
# Container is running
docker ps
# Follow the logs — envGo prints the loaded variable count and route table
docker logs -f envgo
# Static file
curl http://localhost/
# A public-mode route
curl -X POST http://localhost/api/chat \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4","messages":[{"role":"user","content":"Hello"}]}'

Notes about TLS in containers

The generated Caddyfile references certificate files that are not present. For a real deployment, prefer one of these:

  • Let Caddy obtain certificates itself by using a real hostname instead of :443 with explicit tls paths, and mount /data and /config as volumes so certificates survive restarts:
yourdomain.com {
reverse_proxy 127.0.0.1:8080
}
  • Terminate TLS outside the container — at a load balancer or a host-level reverse proxy — and have the container serve plain HTTP on port 80.

See TLS / HTTPS for the full picture.

Next steps