Go apps usually deploy cleanly on Vercel with the native Go preset: a go.mod, a supported entrypoint, and an HTTP server that listens on PORT. But not every Go project fits that shape. Some ship their own startup scripts, depend on external binaries, or are already published as a container image you'd rather run as-is.
Docker often fits those cases better. This guide shows how to deploy a Dockerized Go application on Vercel using Memos, an open-source note-taking app, as an example. Memos runs as a Go server from the neosmemo/memos:stable image and stores durable data in Postgres.
Copy link to headingWhen to run Go using Docker
Use Vercel's native Go Runtime when your app is a standard Go HTTP server with a root go.mod, a supported entrypoint like main.go, and code you can adapt to listen on PORT.
Use Docker when the app:
- Already ships as a maintained OCI image.
- Has a custom entrypoint or runtime behavior you do not want to rewrite.
- Needs operating-system packages, CA bundles, native binaries, or bundled assets.
- Uses a framework or app layout outside Vercel's Go preset assumptions.
- Should run locally and in production from the same image.
- Is an upstream open-source app, like Memos, where you want to configure rather than fork.
Docker on Vercel still runs as a Vercel Function. The container must serve HTTP, stay stateless, use external storage for durable data, and respect Function limits. Vercel builds the image, stores it in Vercel Container Registry, and routes traffic to it.
Copy link to headingHow to run Docker on Vercel
Vercel supports container images through Dockerfile.vercel or Containerfile.vercel. In a Services project, declare the container service in vercel.json and expose it with a rewrite.
Memos is a useful example because it is a Go app, already has an official Docker image, and can switch from local SQLite to Postgres through environment variables.
Copy link to headingAdd Vercel Dockerfile
First, create a Dockerfile.vercel that only runs the upstream Memos image on a port that Vercel can reach:
Here is what each part does:
FROM neosmemo/memos:stableuses the official Memos image instead of rebuilding the Go app from source.MEMOS_ADDR=0.0.0.0makes the server accept traffic from outside the container.MEMOS_PORT=5230keeps Memos on its normal unprivileged port. The image runs as a non-root user, so binding to port80can fail.MEMOS_DATA=/tmp/memosgives Memos a writable local directory. On Vercel this is ephemeral, so it must not be the system of record.EXPOSE 5230documents the container port.
Also, set the Vercel project environment variable PORT=5230. Vercel routes to port 80 by default unless PORT is configured. Memos itself reads MEMOS_PORT, while Vercel's container router reads PORT, so both values matter.
Copy link to headingAdd Postgres from the Vercel Marketplace
The Memos app requires a persistent database service. SQLite is not suitable for durable production data on Vercel Functions. Use a Postgres database integration such as Neon instead. This will provide the data and file storage for the app.
From a linked Vercel project, you can discover and install Neon from the Marketplace with the Vercel CLI.
Install Neon, create a resource, and connect it to the current project:
Copy link to headingConnect Memos to Postgres
Memos needs these settings to use Postgres:
Add MEMOS_DRIVER=postgres to the Dockerfile:
You could manually copy Neon's connection string into a new Vercel environment variable named MEMOS_DSN, but that duplicates a secret. To avoid duplicating the secret, derive MEMOS_DSN at startup.
Add this ENTRYPOINT line to Dockerfile.vercel:
This line does three jobs:
- If
MEMOS_DSNis already set, Memos uses it. - Otherwise, it maps Neon's
DATABASE_URL_UNPOOLEDtoMEMOS_DSN, falling back toDATABASE_URL. - It starts the Memos binary from the upstream image.
The final Dockerfile.vercel looks like this:
Copy link to headingAdd a Services config (optional)
Vercel Services lets you deploy one or more services in a single Vercel project. If you later add a frontend, you can route only a path prefix to the Go container and send everything else to the frontend service:
Copy link to headingDeploy to Vercel
From the project root:
During deployment, Vercel builds the image, pushes it to Vercel Container Registry, creates a Function for the container service, and aliases the production URL.
After deploy, verify the app:
Copy link to headingTroubleshooting
Copy link to headingThe deployment is ready, but the site returns 404
Cause: The container built, but no public route points to it. In Services mode, a service is private until a top-level rewrite exposes it.
Fix: Add rewrites in the vercel.json:
Also, confirm the project framework is set to Services when using services in vercel.json.
Copy link to headingThe container returns 500
Cause: The app is trying to listen on port 80 while running as a non-root user. Memos runs as a non-root user, so binding to privileged ports can fail.
Fix: Set Memos to listen on an unprivileged port:
Then set the Vercel project environment variable:
Vercel uses PORT to decide where to route traffic inside the container. Memos uses MEMOS_PORT to decide where the app listens. You need both.
Copy link to headingBuild logs say no functions or static directory
Cause: In the Services and container path, this warning can appear even when Vercel produced the container-backed Function.
Fix: Inspect the deployment instead of relying only on that warning. The app is deployed as a container image.
Copy link to headingRelated resources
- Vercel Container Images
- Vercel Services
- Vercel Go Runtime
- Memos Docker docs
- Neon and Vercel manual setup
Copy link to headingFAQ
How long can a Dockerized Go app run?
Container image services inherit Vercel Function limits. They are designed for HTTP request handling, not permanent background daemons.
Can I use SQLite inside the container?
Not for durable production data. Vercel containers are stateless and can scale down or be replaced. Use a Postgres database integration, such as Neon, for persistent data.
Can I deploy a frontend and Dockerized Go backend together?
Yes. Use Vercel Services with one frontend service and one container service, then route /api/* or another path to the backend.
Where should I put secrets?
Use Vercel environment variables or integration-injected variables. Do not put database URLs, API keys, or credentials in the Dockerfile or repository.
Can I use WebSockets with a Dockerized Go app?
Vercel supports WebSockets for Vercel Functions on Fluid compute, including container-image Functions, with current platform limits. For long-lived connections, design clients to reconnect.