Deploy guide
Deploy any app with a Dockerfile to TOSE
Any language works on TOSE when the repository has a Dockerfile. TOSE builds it and runs the container on the project port.
Before you start
- A GitHub repository with a file named Dockerfile at its root.
- The container serves HTTP on one port, 3000 unless you change the project port.
- A TOSE account and a workspace at app.tose.sh, with the repository connected through the TOSE GitHub App.
- Node.js, to install the TOSE CLI: npm install -g @tosesh/tose. You can also do every step in the dashboard.
The example
These files are the example app in the tose-web repository. Its test builds the image for linux/amd64, starts the container and requests the page.
FROM node:22-alpine
WORKDIR /app
COPY server.js ./
USER node
ENV PORT=3000
EXPOSE 3000
CMD ["node", "server.js"]const http = require('node:http');
const port = Number(process.env.PORT || 3000);
http
.createServer((req, res) => {
res.writeHead(200, { 'content-type': 'text/plain' });
res.end('Hello from a Dockerfile on TOSE\n');
})
.listen(port, '0.0.0.0', () => console.log(`listening on 0.0.0.0:${port}`));Deploy it
1. Put the Dockerfile at the root of the repository
TOSE builds the file named Dockerfile at the repository root.
2. Check the image locally
TOSE builds for linux/amd64. Build for the same platform and open http://localhost:3000.
docker build --platform linux/amd64 -t my-app . docker run --rm -p 3000:3000 my-app3. Create the project
In the dashboard, create a project from the GitHub repository and keep port 3000, or run tose up in the repository and answer its questions. Either way you do this once.
tose up4. Deploy and check
Every later deploy is one command. Use the build log when the build fails and the live log when the app does not answer.
tose deploy my-workspace/my-app --json tose status my-workspace/my-app --json tose logs my-workspace/my-app --build -n 200 tose logs my-workspace/my-app -n 1005. Set environment variables
Select the project, set variables, then redeploy so the container starts with them. Never commit secrets to the repository.
tose use my-workspace/my-app tose env set DATABASE_URL=… API_BASE_URL=… tose redeploy
Notes for this stack
- The example is a Node.js server, but the rules are the same for Python, Ruby, PHP, Rust or Java: bind 0.0.0.0, listen on the project port, and keep data you need on a persistent disk.
- Without a Dockerfile, TOSE detects common stacks (package.json, go.mod and others) and generates one. Commit your own when you need a predictable build.
Size and cost
- A new project gets 1 vCPU, 2 GB RAM and 1 replica. You can change vCPU and RAM in the dashboard to 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16.
- Until the workspace wallet has a positive balance, a project can use at most 2 vCPU and 2 GB RAM.
- At the base price, the default size costs $29.20 for a month of 730 hours.
When something fails
- "no Dockerfile in project and OPENROUTER_KEY not configured for AI generation"
- TOSE found no Dockerfile. Add one named exactly Dockerfile at the repository root.
- "AI Dockerfile generation failed"
- TOSE could not generate a Dockerfile for this repository. Commit your own, starting from the example on this page.
- The deploy finishes but the app does not answer or keeps restarting
- The app must listen on 0.0.0.0 and on the project port (3000 by default). TOSE does not set PORT for you; set it in the Dockerfile or with tose env set. Read tose logs for the crash.
- The build stops without an error from your code
- Builds get 2 GB of memory, 2 CPUs and 45 minutes. Cut build memory (for example fewer parallel jobs) or install fewer dependencies.
- "exec format error" when the container starts
- The image or a binary in it is not for linux/amd64. Use base images that publish amd64 and do not pin another platform.