Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

An MVC web stack written in Fortran 90 (so you get arrays, and it's not punchcards)

Major credit due to:

Create an Ubuntu server

Log in and install dependencies

# update Ubuntu
sudo apt-get update
sudo apt-get upgrade

# create the user and home directory
adduser fortran --gecos ""
usermod -a -G sudo fortran

# switch to new user
su fortran
cd ~

# install git and clone the repo
sudo apt-get install -y git
git clone

# Install dependencies
cd fortran-machine
sudo ./

Go to your IP address - you should see the "Welcome to nginx!" page

Change the location in /etc/nginx/sites-available/default :

server_name; <- your IP address

location / {
	root /home/fortran/fortran-machine;
	index index.html;

Restart nginx to make these settings for real:

sudo service nginx restart

You should now see the test page on your IP address.

Test doc

Use Fortran CGI script

Let's go from test page to Fortran script:

# compile the test server

Now change nginx config /etc/nginx/sites-available/default

location / {
	root /home/fortran/fortran-machine;
	fastcgi_index index.html;
	include fastcgi_params;

Then run sudo service nginx restart

# spawn the server
spawn-fcgi -a -p 9000 ./fortran_fcgi

Restarting the script

After changing the source code, you can recompile and restart your server with:


Add a static folder

Add to nginx config /etc/nginx/sites-available/default

location /static {
    root /home/fortran/fortran-machine;

And restart nginx

sudo service nginx restart

Fortran controller

The controller is written in Fortran in the fortran_fcgi.f90 file:

case ('/')
	! most pages look like this
	templatefile = 'template/index.jade'
	call jadefile(templatefile, unitNo)

case ('/search')
	write(unitNo,AFORMAT) '<div class="container">'

	templatefile = 'template/search.jade'
	call jadefile(templatefile, unitNo)

	write(unitNo,AFORMAT) '</div>'

Jade Templates

In the template folder, you can write HTML templates similar to Jade or HAML.

If you want to have a loop or other structure, it's better to create a partial and run the loop in the Fortran controller.

    h3 Hello #{name}!
    h3 Link
    a(href="{id}") A link

SQLite Database

You can connect to a SQLite database. The example on lets you search through marsupials!

Here's how the getAllMarsupials subroutine loads data into arrays:

subroutine getAllMarsupials(name, latinName, wikiLink, description)
	! columns
	character(len=50), dimension(8)	:: name, latinName, wikiLink, description

	call sqlite3_open('marsupials.sqlite3', db)

	allocate( column(4) )
	call sqlite3_column_query( column(1), 'name', SQLITE_CHAR )
	call sqlite3_column_query( column(2), 'latinName', SQLITE_CHAR )
	call sqlite3_column_query( column(3), 'wikiLink', SQLITE_CHAR )
	call sqlite3_column_query( column(4), 'description', SQLITE_CHAR )

	call sqlite3_prepare_select( db, 'marsupials', column, stmt, "WHERE 1=1 LIMIT 8")

	i = 1
		call sqlite3_next_row(stmt, column, finished)
		if (finished) exit

		call sqlite3_get_column(column(1), name(i))
		call sqlite3_get_column(column(2), latinName(i))
		call sqlite3_get_column(column(3), wikiLink(i))
		call sqlite3_get_column(column(4), description(i))
		i = i + 1
	end do

Then in the Fortran controller, you loop through:

call getAllMarsupials(names, latinNames, wikiLinks, descriptions)

i = 1
	pagevars(1,2) = names(i)
	pagevars(2,2) = latinNames(i)
	pagevars(3,2) = wikiLinks(i)
	pagevars(4,2) = descriptions(i)
	if (len(trim(pagevars(1,2))) == 0 .or. i == 5) then
		! template with string
		templatefile = 'template/result.jade'
		call jadetemplate(templatefile, unitNo, pagevars)
		i = i + 1

Then the individual result template:

      a(href="{wikiLink}") #{name}
    em #{latinName}
    p #{description}

HTTPS Certificate

Don't forget to get a free HTTPS Certificate using LetsEncrypt!


This library, like FLIBS which it's based on, is available under the BSD license