Deployment
Cloud Providers
Linode (Akamai)

Step 1 — Launch the StackScript

Deploy rtSurvey on Linode → (opens in a new tab)

This opens the StackScript page in Linode Cloud Manager. Click Deploy New Linode.


Step 2 — Fill in Linode's form

Fill in Linode's standard server creation form:

FieldRecommended value
ImageUbuntu 22.04 LTS
RegionClosest to your users
PlanShared CPU 4 GB or larger
Root PasswordSet a strong password
FirewallNo Firewall (recommended)
Timezone (our only field)Your server timezone (default: Asia/Ho_Chi_Minh)

Why no firewall? The setup script needs outbound internet access (Docker pulls, Let's Encrypt). Blocking ports during first boot can cause the deployment to fail. You can attach a firewall after setup is complete — see Firewall rules below for the correct rules.

Click Create Linode when done.


Step 3 — Wait for setup to complete

The script runs automatically on first boot. It installs Docker, pulls the rtSurvey image, initialises the database, and starts all services. This takes 5–10 minutes.

No console access needed. Just open your browser and navigate to your domain (or the server IP) after about 2–3 minutes. You will see a branded loading page while the app finishes starting up. The page refreshes automatically every 20 seconds. Once the app is fully started, it loads automatically — no manual refresh needed.

Tip: The server IP is shown in the Linode dashboard (opens in a new tab) on the Linode detail page. If DNS is already pointing to the server, you can use your domain name directly.


Step 4 — Set up SSL

Once the loading page disappears and the app is running, follow the Set Up SSL guide → to configure HTTPS. The free rtsurvey.com subdomain is the fastest option — no DNS setup needed.


Step 5 — Change the default password

All passwords default to admin. Change them immediately after your first login:

  • App admin password — account settings inside the app
  • Keycloak admin — accessible at https://your-domain.com/auth/admin (login: admin / admin)

Firewall rules (Linode Cloud Firewall)

If you attach a Linode Cloud Firewall to this server, use the following rules:

Inbound

LabelActionProtocolPortSourcesNotes
accept-inbound-sshAcceptTCP22All IPv4, All IPv6SSH access
accept-inbound-httpAcceptTCP80All IPv4, All IPv6Nginx (HTTP + ACME challenge)
accept-inbound-httpsAcceptTCP443All IPv4, All IPv6Nginx (HTTPS after SSL setup)
accept-inbound-shinyAcceptTCP3838All IPv4, All IPv6Shiny Server (R analytics)
accept-inbound-icmpAcceptICMPAll IPv4, All IPv6Ping / diagnostics
Default inbound policyDropBlock everything else

Outbound

LabelActionNotes
Default outbound policyAcceptAllow all outbound (Docker pulls, certbot, GoDaddy API, etc.)

Ports NOT needed externally

These ports are bound to 127.0.0.1 only and never reachable from outside the server:

PortServiceReason
8080App containerNginx proxies to it internally
8090Keycloak containerNginx proxies to it internally
3306MySQLInternal Docker network only

Troubleshooting

Check the setup log

tail -200 /var/log/stackscript.log

Check the SSL log

tail -200 /var/log/rtsurvey-ssl.log

View container status

docker compose -f /opt/rtsurvey/docker-compose.production.yml ps