Deployment with view templates (Fly.io)
Learning objectives
- You know how to deploy an application that uses view templates.
In this example, we continue directly from the example outlined in Deploying on a server (Fly.io), where we deployed a Deno application on Fly.io. Presently, the content of the app
folder in the downloaded walking skeleton is as follows.
ls
app.js Dockerfile fly.toml
That is, in addition to the app.js
and the Dockerfile
, there is a fly.toml
file that contains the Fly.io configuration used to deploy the application on the server.
A note on deployment
This part provides similar guidelines to deployment as the previous part on Deployment with view templates (Render). The key difference is that here, we outline how the same task is accomplished with Fly.io.
The service Fly.io that is outlined here requires credit card (from some participants). When used within the free tier limits, the credit card will not be billed.
Adding a view template and a layout
Let's create a folder views
and a folder layouts
into the folder views
. Create a file called layout.eta
and place it into the layouts
folder. Place the following contents to the layout.eta
file. Here, we use PaperCSS
for styles.
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
<link rel="stylesheet" href="https://unpkg.com/papercss@1.8.1/dist/paper.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="utf-8">
</head>
<body>
<div class="container paper">
<%~ it.body %>
</div>
</body>
</html>
Now, create a file called count.eta
and place it to the views
folder. Place the following contents to the count.eta
file.
<% layout('./layouts/layout.eta') %>
<h1>Current count: <%= it.count %></h1>
At this point, the contents of the app
folder should be as follows.
tree --dirsfirst
.
├── views
│ ├── layouts
│ │ └── layout.eta
│ └── count.eta
├── app.js
├── Dockerfile
└── fly.toml
Using view templates
Now, we adjust the app.js
so that it uses the view templates. In the following, we add the view template library, configure it, create a variable to store the count
that we show on the page, and modify the handleRequest
function so that it is asynchronous and so that it shows the view template on requests to the path /count
.
The contents of the file are now as follows -- note that requests to other paths than /count
still show the message Meaning of life: 42
.
import { serve } from "https://deno.land/std@0.222.1/http/server.ts";
import { configure, renderFile } from "https://deno.land/x/eta@v2.2.0/mod.ts";
configure({
views: `${Deno.cwd()}/views/`,
});
const responseDetails = {
headers: { "Content-Type": "text/html;charset=UTF-8" },
};
const data = {
count: 0,
};
const handleRequest = async (request) => {
const url = new URL(request.url);
if (url.pathname === "/count") {
data.count++;
return new Response(await renderFile("count.eta", data), responseDetails);
}
return new Response("Meaning of life: 42");
};
serve(handleRequest, { port: 7777 });
Testing the application locally, things are in order.
Authenticating and deploying
To deploy the application, we must first again authenticate using flyctl auth login
. Before that, we verify that we are in the correct folder.
tree --dirsfirst
.
├── views
│ ├── layouts
│ │ └── layout.eta
│ └── count.eta
├── app.js
├── Dockerfile
└── fly.toml
2 directories, 5 files
flyctl auth login
Opening https://fly.io/app/auth/cli/(hash) ...
Waiting for session... Done
successfully logged in as (your email)
Now, we use the flyctl deploy
command to deploy our application.
ls
app.js Dockerfile fly.toml views/
flyctl deploy
==> ... (plenty of stuff)
==> ... (waiting and waiting)
1 desired, 1 placed, 1 healthy, 0 unhealthy ..
--> v2 deployed successfully
This deploys the application replacing our previous version.
Accessing the application
When we open up the application, it is up and running.
flyctl open
opening (address to your application) ...

When we access the path /count
, we see the page with count. The page is also styled as expected.

Count resets on server restarts
Note that whenever the server is restarted, the count is reset. This is because the count is not stored in any location. We'll look into addressing this when we start working with databases.