Skip to content

Updating visuals

If you see any images containing outdated UI, please bear with us.

We are updating all content as quickly as possible to mirror our new UI.

Self-host a fullstack app on AWS (coming soon) ​

This page is a draft for the intended AWS setup for self-hosting a fullstack WeWeb app. The guide is coming soon and is not a working guide yet.

COMING SOON

At the moment, it is not yet possible to have a functioning self-hosted fullstack WeWeb app.

You can still self-host the interface today, but the fullstack setup described on this page is not ready to use yet.

Current status ​

  • Interface self-hosting is available today.
  • Fullstack self-hosting is not available yet.
  • The guide is coming soon.
  • The steps below are draft notes for the intended setup once the export flow is finalized.

Before you start ​

Make sure you have:

  1. An AWS account.
  2. A WeWeb project that has already been published at least once.
  3. Access to code export.
  4. One AWS region selected for your main resources. Try to keep your S3, EC2, and RDS resources in the same region.

What this setup looks like ​

  • S3 Stores the built interface files.
  • CloudFront Serves the app and forwards /api/* requests to your backend.
  • EC2 Runs the exported backend on port 3030.
  • RDS Stores your PostgreSQL data.
  • S3 Can also store public and private files for uploads.

Export your project from WeWeb ​

  1. In WeWeb, go to Deploy → Export.
  2. Click Generate code export.
  3. Download the built interface zip.
  4. Download the backend export zip.

Host the interface on AWS ​

Prepare the interface files ​

  1. Unzip the built interface archive on your computer.
  2. Rename the extracted folder to front.

Create an S3 bucket ​

  1. In AWS, go to S3.
  2. Click Create bucket.
  3. Choose a unique bucket name, for example acme-my-weweb-app-prod.
  4. Leave the other settings unchanged unless your team needs something more specific.
  5. Open the bucket and upload the front folder.

Create a CloudFront distribution ​

  1. In AWS, go to CloudFront.
  2. Create a new distribution.
  3. Select your S3 bucket as the origin.
  4. Set the origin path to /front.
  5. Finish creating the distribution.
  6. Open the distribution settings and set the default root object to index.html.
  7. Wait a few minutes for the distribution to finish deploying.
  8. Open the CloudFront domain to confirm the interface loads.

ROUTING

If your app uses custom paths or dynamic URL parameters, you may also need rewrite rules so direct links and page refreshes keep working. See the related guide at the end of this page.

INTERFACE-ONLY PROJECTS

If your project only uses the interface and does not rely on any backend services, database hosting, file storage, or authentication hosting, you can stop here. The rest of this guide is only needed for the fullstack setup.

Create the backend server ​

Launch an EC2 instance ​

  1. In AWS, go to EC2.
  2. Launch a new instance with the latest Amazon Linux 2023 image.
  3. Choose an instance size that fits your expected traffic. t3.micro can work for testing, but larger projects may need more resources.
  4. Create a key pair and save the .pem file somewhere safe.
  5. Create a security group that allows SSH from My IP.
  6. Launch the instance and note the public IPv4 address.

On your computer, secure the key and connect:

bash
chmod 600 your-key-pair.pem
ssh -i your-key-pair.pem ec2-user@your-ec2-ipv4

Install Node.js ​

Install Node.js 24 on the instance:

bash
sudo dnf install nodejs24
node -v

Some older guides may still show sudo yum install nodejs24, but for Amazon Linux 2023 you should prefer dnf.

You should see a version that starts with v24.

Update the security group ​

Once the instance is running, update the inbound rules so your backend can be reached:

RequiredTypePortSourceWhy
YesSSH22Your IPLets you connect to the instance
YesCustom TCP3030com.amazonaws.global.cloudfront.origin-facingLets CloudFront reach your backend
OptionalCustom TCP3030Your IPLets you test the backend directly

Allocate a static IP ​

  1. In AWS, go to Elastic IPs.
  2. Click Allocate Elastic IP address.
  3. Select the new IP and choose Associate Elastic IP address.
  4. Attach it to the EC2 instance you just created.

Install the exported backend ​

Upload the backend files ​

  1. From your computer, copy the backend zip file to the server:
bash
scp -i your-key-pair.pem weweb-export.zip ec2-user@your-ec2-ipv4:/home/ec2-user
  1. Connect to the server again:
bash
ssh -i your-key-pair.pem ec2-user@your-ec2-ipv4
  1. Unzip the backend archive in a temporary folder.

Update the environment file ​

Open the exported .env file and update it with your values:

  • DATABASE_URL: Your full PostgreSQL connection string.
  • APP_URL: The public app URL your backend should accept.
  • SERVER_URL: The public backend URL.

Move the files into place ​

Move the environment file and server file into dedicated folders:

bash
sudo mkdir -p /etc/myapp /myapp
sudo mv .env /etc/myapp/env
sudo mv index_server.mjs /myapp/
sudo chmod 600 /etc/myapp/env
sudo chmod 755 /myapp
sudo chmod 644 /myapp/index_server.mjs
sudo chown ec2-user:ec2-user /etc/myapp/env
sudo chown ec2-user:ec2-user /myapp/index_server.mjs

Run the backend with systemd ​

Create a service file at /etc/systemd/system/myapp.service:

ini
[Unit]
Description=My WeWeb Backend
After=network.target

[Service]
User=ec2-user
WorkingDirectory=/myapp
ExecStart=/usr/bin/node-24 /myapp/index_server.mjs
Restart=always
RestartSec=5
EnvironmentFile=/etc/myapp/env

[Install]
WantedBy=multi-user.target

Then load and start the service:

bash
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

If you allowed your IP on port 3030, you can test the backend directly:

bash
curl http://your-ec2-ipv4:3030/api/ww/health

Route API requests through CloudFront ​

  1. Open the CloudFront distribution you created for the interface.
  2. Add a second origin for your backend. Use your backend domain name or public EC2 DNS name as the origin.
  3. In Behaviors, create a new behavior for /api/*.
  4. Point that behavior to the backend origin.
  5. Save the changes and wait for the distribution to update.

Then test:

txt
https://your-distribution-domain-name/api/ww/health

If everything is set up correctly, this should return a healthy response from your backend.

Create a PostgreSQL database in RDS ​

  1. In AWS, go to RDS.
  2. Create a new database with the PostgreSQL engine.
  3. Keep it in the same region as your backend when possible.
  4. During connectivity setup, allow the database to be reached from the EC2 instance you created.
  5. Finish the setup and note the database endpoint, username, password, and port.

Connect the backend to RDS ​

  1. Apply your database schema using the files or process provided by your export.
  2. On the server, update DATABASE_URL in /etc/myapp/env so it points to the new RDS database.
  3. Restart the service:
bash
sudo systemctl restart myapp

DATABASE SETUP

If your current export does not yet include a ready-to-run SQL schema file, you will need to create the schema using your existing migration or database setup process.

Set up file storage in S3 ​

If your project uses file uploads, create two buckets:

  1. One public bucket.
  2. One private bucket.

Example names:

  • acme-myapp-storage-public
  • acme-myapp-storage-private

Create an IAM policy ​

  1. Go to IAM → Policies.
  2. Create a new policy from the JSON tab.
  3. Replace the bucket names in the example below:
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3Access",
      "Effect": "Allow",
      "Action": ["s3:*"],
      "Resource": [
        "arn:aws:s3:::acme-myapp-storage-public",
        "arn:aws:s3:::acme-myapp-storage-public/*",
        "arn:aws:s3:::acme-myapp-storage-private",
        "arn:aws:s3:::acme-myapp-storage-private/*"
      ]
    }
  ]
}
  1. Save the policy, for example as myapp-s3-access.

Create an IAM user ​

  1. Go to IAM → Users.
  2. Create a new user, for example myapp.
  3. Attach the myapp-s3-access policy.
  4. Open the new user.
  5. In Security credentials, create an access key.
  6. Copy the access key ID and secret access key right away.

Add the storage settings to the backend ​

On your server, update /etc/myapp/env with values like these:

txt
STORAGE_INTEGRATION=aws-s3
STORAGE_CONNECTION_ID=...
STORAGE_PUBLIC_BUCKET=acme-myapp-storage-public
STORAGE_PRIVATE_BUCKET=acme-myapp-storage-private
AWS_S3_REGION=us-east-1
AWS_S3_ACCESS_KEY_ID=...
AWS_S3_SECRET_ACCESS_KEY=...

Then restart the backend:

bash
sudo systemctl restart myapp

Host authentication ​

COMING SOON

Authentication setup for the fullstack AWS deployment is not documented yet.

Common pitfalls ​

Mixed regions ​

If your buckets, server, and database are spread across different regions, setup becomes harder and requests can fail or slow down. Keep your main AWS resources in the same region whenever possible.

The interface loads but /api/* fails ​

This usually means the CloudFront behavior for /api/* is missing or points to the wrong origin. Double-check the behavior and make sure the backend is reachable on port 3030.

Direct backend checks work, but CloudFront cannot reach it ​

Check the EC2 security group. The backend must allow incoming traffic on port 3030 from the AWS-managed CloudFront origin-facing prefix list.

The backend starts but cannot reach the database ​

Review the DATABASE_URL, the RDS security settings, and whether the database is reachable from the EC2 instance.

File uploads do not work ​

Check the bucket names, region, IAM policy, and access keys in /etc/myapp/env. A small typo in any of these values can stop uploads from working.

Continue learning

If your app uses dynamic URL parameters or deep links, the next guide explains how to handle routing so refreshes and direct links keep working on self-hosted setups.

Learn more about self-hosting with dynamic routing →