•3 min read•Tutorial
Deploying Deno Applications: From Development to Production
Learn how to deploy Deno applications to production with Deno Deploy, Docker, and other platforms
Deploying Deno Applications
Deploying Deno apps is straightforward with modern platforms. Here's how to deploy to production securely and efficiently.
Deployment Options
1. Deno Deploy (Easiest)
# Install deployctl
deno install --allow-all --no-check -r -f https://deno.land/x/deploy/deployctl.ts
# Deploy
deployctl deploy --project=my-app server.ts
server.ts:
Deno.serve((req) => new Response("Hello from Deno Deploy!"));
2. Docker
Dockerfile:
FROM denoland/deno:1.38.5
WORKDIR /app
COPY . .
RUN deno cache server.ts
EXPOSE 8000
CMD ["deno", "run", "--allow-net", "--allow-read", "--allow-env", "server.ts"]
Build and run:
docker build -t my-deno-app .
docker run -p 8000:8000 my-deno-app
3. Kubernetes
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deno-app
spec:
replicas: 3
selector:
matchLabels:
app: deno-app
template:
metadata:
labels:
app: deno-app
spec:
containers:
- name: deno-app
image: my-deno-app:latest
ports:
- containerPort: 8000
env:
- name: PORT
value: "8000"
4. DigitalOcean/AWS/GCP
# Using systemd service
# /etc/systemd/system/deno-app.service
[Unit]
Description=Deno Application
After=network.target
[Service]
Type=simple
User=deno
WorkingDirectory=/home/deno/app
ExecStart=/home/deno/.deno/bin/deno run --allow-net --allow-read --allow-env server.ts
Restart=always
[Install]
WantedBy=multi-user.target
# Enable and start
sudo systemctl enable deno-app
sudo systemctl start deno-app
Production Best Practices
1. Environment Variables
// config.ts
const config = {
port: parseInt(Deno.env.get("PORT") || "8000"),
database: {
url: Deno.env.get("DATABASE_URL") || "",
poolSize: parseInt(Deno.env.get("DB_POOL_SIZE") || "10"),
},
auth: {
secret: Deno.env.get("AUTH_SECRET") || "",
},
};
export default config;
2. Logging
import * as log from "@std/log";
await log.setup({
handlers: {
console: new log.handlers.ConsoleHandler("DEBUG"),
file: new log.handlers.FileHandler("INFO", {
filename: "./app.log",
mode: "a",
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["console", "file"],
},
},
});
log.info("Server starting...");
log.error("Error occurred", { error });
3. Health Checks
router.get("/health", (ctx) => {
ctx.response.body = {
status: "healthy",
timestamp: new Date().toISOString(),
uptime: Deno.metrics().ops.now / 1000,
};
});
4. Graceful Shutdown
const server = Deno.serve({ port: 8000 }, handler);
Deno.addSignalListener("SIGTERM", async () => {
console.log("SIGTERM received, shutting down gracefully");
await server.shutdown();
await cleanup();
Deno.exit(0);
});
Security Checklist
- Use specific permissions (not --allow-all)
- Validate environment variables
- Use HTTPS in production
- Implement rate limiting
- Add security headers
- Sanitize user input
- Use helmet-style middleware
Monitoring
// Simple metrics endpoint
let requestCount = 0;
let errorCount = 0;
router.get("/metrics", (ctx) => {
ctx.response.body = {
requests: requestCount,
errors: errorCount,
memory: Deno.memoryUsage(),
};
});
Performance Tips
- Cache dependencies
deno cache --reload server.ts
- Use appropriate permissions
deno run --allow-net=:8000 --allow-read=./static server.ts
- Enable HTTP/2
Deno.serve({
port: 8000,
cert: await Deno.readTextFile("./cert.pem"),
key: await Deno.readTextFile("./key.pem"),
}, handler);
Conclusion
Deploy Deno apps with confidence using:
- Deno Deploy for serverless
- Docker for containers
- Systemd for VPS
- Proper logging and monitoring
- Security best practices
Start deploying today!
👨💻
Jordan Patel
Web Developer & Technology Enthusiast