Home Host a website or app Host an app that runs code (Node.js, Python and others)

Host an app that runs code (Node.js, Python and others)

Last updated on Sep 16, 2026

A website made of files is served straight from a folder. An app is a program that has to keep running, and it usually listens on its own port such as 3000 or 8000. Two things are needed: keep it running, and let visitors reach it on the normal web ports.

This article assumes your developer gave you the code and the command that starts it.

1. Upload the code

Put it in your home folder rather than the web folder, because visitors should never download the source:

/home/ubuntu/myapp

Use FileZilla, or ask your developer to deploy with git.

2. Run it as a service

A program started by hand stops when you close the terminal. A service starts again by itself, including after a reboot. Create one:

sudo nano /etc/systemd/system/myapp.service

Paste this, change the three lines in bold to match your app, then save with Ctrl+O and exit with Ctrl+X:

[Unit]
Description=My application
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/usr/bin/node server.js
Restart=always

[Install]
WantedBy=multi-user.target

WorkingDirectory is where your code lives, and ExecStart is the command that starts it (for Python it might be /usr/bin/python3 app.py). Then:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp

active (running) means it started. If it failed, read the reason:

journalctl -u myapp -n 50 --no-pager

3. Put it behind the web server

Your app listens on something like port 3000, which is not open to the internet and should stay that way. Apache takes the visitor's request on port 80 and passes it to your app:

sudo a2enmod proxy proxy_http
sudo nano /etc/apache2/sites-available/000-default.conf

Inside <VirtualHost *:80>, add these lines (change 3000 if your app uses another port):

ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
sudo systemctl restart apache2

Now http://your-domain reaches your app, and port 3000 stays private. Add HTTPS the same way as any site: Turn on HTTPS.

React, Vue and other built sites

If your developer says the app is "built" into a folder of files (often called dist or build), it is not an app in this sense. Upload the contents of that folder to /var/www/html and follow Set up your server so a browser can open your site instead.

Databases

For anything beyond a small site, use a managed database rather than running one on the same server: we handle the backups and the updates. See Create a managed database.