diff --git a/demo_fly_postgres/Dockerfile b/demo_fly_postgres/Dockerfile
deleted file mode 100644
index bbf1fd8c1bd79a319a5819201a1dda60a241657f..0000000000000000000000000000000000000000
--- a/demo_fly_postgres/Dockerfile
+++ /dev/null
@@ -1,39 +0,0 @@
-# syntax = docker/dockerfile:1
-
-# Adjust NODE_VERSION as desired
-ARG NODE_VERSION=20.9.0
-FROM node:${NODE_VERSION}-slim as base
-
-LABEL fly_launch_runtime="Node.js"
-
-# Node.js app lives here
-WORKDIR /app
-
-# Set production environment
-ENV NODE_ENV="production"
-
-
-# Throw-away build stage to reduce size of final image
-FROM base as build
-
-# Install packages needed to build node modules
-RUN apt-get update -qq && \
-    apt-get install -y build-essential pkg-config python-is-python3
-
-# Install node modules
-COPY --link package-lock.json package.json ./
-RUN npm ci
-
-# Copy application code
-COPY --link . .
-
-
-# Final stage for app image
-FROM base
-
-# Copy built application
-COPY --from=build /app /app
-
-# Start the server by default, this can be overwritten at runtime
-EXPOSE 3000
-CMD [ "npm", "run", "start" ]
diff --git a/demo_fly_postgres/app/server.js b/demo_fly_postgres/app/server.js
index 00d6de9f4f39414e0e6634ae3d4a9f166a945309..6b23d8c6e883c171f804b4ee2ed076ea4b8ad167 100644
--- a/demo_fly_postgres/app/server.js
+++ b/demo_fly_postgres/app/server.js
@@ -32,6 +32,11 @@ pool.connect().then(() => {
 	console.log("Connected to db");
 });
 
+/*
+KEEP EVERYTHING ABOVE HERE
+REPLACE THE FOLLOWING WITH YOUR SERVER CODE 
+*/
+
 app.post("/datum", (req, res) => {
 	let { datum } = req.body;
 	if (datum === undefined) {
@@ -54,6 +59,10 @@ app.get("/data", (req, res) => {
 	})
 })
 
+/*
+KEEP EVERYTHING BELOW HERE
+*/
+
 app.listen(port, host, () => {
 	console.log(`http://${host}:${port}`);
 });
diff --git a/demo_fly_postgres/env.sample b/demo_fly_postgres/env.sample
index 35d70ac87b2c2d17ced6e09c9bee2e5d08f5ea0b..edca9774c9374682c12ab399d62a7e2234ca92ed 100644
--- a/demo_fly_postgres/env.sample
+++ b/demo_fly_postgres/env.sample
@@ -1,6 +1,7 @@
-# rename this to .env to get code to run locally
+# copy this to .env and change the following variables
+# to get your project code to run locally
 PGUSER=YOURPOSTGRESUSER
 PGPORT=5432
 PGHOST=localhost
-PGPASSWORD=YOURPASSWORD
+PGPASSWORD=YOURPOSTGRESPASSWORD
 PGDATABASE=YOURFLYWEBAPPNAME
diff --git a/demo_fly_postgres/fly.toml b/demo_fly_postgres/fly.toml
deleted file mode 100644
index b889cbf40fc1558b083b3d56f46487addc7d4235..0000000000000000000000000000000000000000
--- a/demo_fly_postgres/fly.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-# fly.toml app configuration file generated for wxvsrhsmnh on 2023-12-08T13:12:16-05:00
-#
-# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
-#
-
-app = "wxvsrhsmnh"
-primary_region = "ewr"
-
-[build]
-
-[http_service]
-  internal_port = 3000
-  force_https = true
-  auto_stop_machines = true
-  auto_start_machines = true
-  min_machines_running = 0
-  processes = ["app"]
-
-[[vm]]
-  cpu_kind = "shared"
-  cpus = 1
-  memory_mb = 1024
diff --git a/demo_fly_postgres/package.json b/demo_fly_postgres/package.json
index 693b59d18825b8c3f90cd9dd9ca16f0e09845973..41671ddf8170cbe25ccb88608fa220946398efe9 100644
--- a/demo_fly_postgres/package.json
+++ b/demo_fly_postgres/package.json
@@ -1,9 +1,9 @@
 {
   "scripts": {
     "start": "node app/server.js",
-    "setup": "fly postgres connect -a FLYPOSTGRESAPPNAME < setup.sql",
-    "start:dev": "env-cmd node app/server.js",
-    "setup:dev": "env-cmd psql -d postgres -f setup.sql"
+    "setup": "fly postgres connect -a YOURFLYPOSTGRESAPPNAME < setup.sql",
+    "start:local": "env-cmd node app/server.js",
+    "setup:local": "env-cmd psql -d postgres -c 'CREATE DATABASE YOURFLYWEBAPPNAME' -f setup.sql"
   },
   "dependencies": {
     "env-cmd": "^10.1.0",
diff --git a/demo_fly_postgres/readme.md b/demo_fly_postgres/readme.md
index fdac1f4e743f56798056021529f4c7b18fac6184..b24f76a445c32068c857aefa590b8e9586a53587 100644
--- a/demo_fly_postgres/readme.md
+++ b/demo_fly_postgres/readme.md
@@ -1,90 +1,86 @@
 
 # Demo Fly Postgres
 
-This demo shows you how to deploy a website to Fly with a Postgres database.
-
-**Make sure to follow all instructions carefully.**
+[Fly](https://fly.io/) is a platform for deploying web apps. This demo shows you how to deploy a website to Fly with a Postgres database.
 
 ## Billing
 
 fly.io's pay as you go plan will charge you based on usage, but as of 2024-08-07, they have a secret policy that if your monthly bill is < $5, they'll waive your bill. Most groups will probably qualify for this. If not, I'd expect your bill to be no more than $5, and definitely no more than $10, as long as you select "Development" and not "Production" when deploying. If this is an issue for you, let me know and we can work something out.
 
-## Set up web app configuration, deploy Postgres app
+## Overview
+
+The easiest way to use this demo is to clone this repo, copy this folder somewhere else, follow _all_ of the below instructions, and then paste your project-specific code as directed into these files.
+
+## Deploying your web and Postgres Fly apps
+
+From the command line, in this folder, run `fly launch` and enter `y` to change settings. This will open a webpage in your browser. Make the following selections:
+
+1) Pick an app name. It has to be unique across all Fly apps currently deployed. You'll use this app name to refer to your Fly web app and it'll be part of the URL you visit to view your deployed site.
+	- Make sure this is a valid variable name and don't use any punctuation, as this will make it easier to use it later.
+2) Check that the internal port matches the port your server.js listens on. If it doesn't, change either one of them to match.
+3) Select Fly Automated Postgres as the Postgres provider.
+4) Make your Postgres app name equal to your web app name + `db`. For example, if your Fly web app name was `abc`, name your Fly Postgres app `abcdb`.
+5) **Make sure the Postgres configuration is Development, _not_ Production.** This will cost less money.
+6) Click confirm settings when you're done.
+
+`fly launch` will then continue running in your terminal (this may take a few minutes). At some point, it'll print out your deployed Postgres cluster's credentials. Save these in a text file somewhere private (don't commit them to your repo) just in case you need them later, as once you close the terminal, you'll never see them again.
+
+`fly launch` will have created a fly.toml and a Dockerfile in your project folder. Commit these to your repo. You shouldn't need to modify these.
+
+## Local changes
+
+You'll need to make these changes so you can run this code locally and set up both your deployed and local databases:
+
+- Copy `env.sample` into a file named `.env`.
+	- Keep the original env.sample so people who clone your repo know what credentials they need to put inside .env.
+- In `.env`, replace `YOURPOSTGRESUSER` and `YOURPOSTGRESPASSWORD` with your **local** Postgres username and password.
+- In `.env`, replace `YOURFLYWEBAPPNAME` with the Fly **web** app name you selected when running `fly launch`.
+- In `setup.sql`, replace `YOURFLYWEBAPPNAME` with your Fly **web** app name.
+- In `package.json`, replace `YOURFLYPOSTGRESAPPNAME` with your Fly **Postgres** app name and `YOURFLYWEBAPPNAME` with your Fly **web** app name.
+
+There's already a `.gitignore` file which ignores `.env` in this folder, so you don't need to create that.
+
+## Setting up your deployed and local Postgres databases
 
-- Follow steps 1 - 3 [here](https://fly.io/docs/speedrun/) if you don't already have a Fly account and to install the fly command line program
-- `fly launch` will fail if you don't have a credit card on file; see [here](https://fly.io/docs/about/pricing/) and above for information on billing
-- Then when running `fly launch`, when prompted "Do you want to tweak these settings before proceeding?", enter `y`, will take you to webpage
-	- Choose unique app name, can't match any other existing fly apps globally
-		- Note that your app name will also have to become your database name; see the creating database tables section below
-		- **Make your app name a valid variable name, as we'll be using it later on**. The default generated names have hyphens in them - don't use any hyphens
-	- Check that the port your server.js listens on matches what's on the Fly page, and if not, change either so they match
-	- Under database section, select Fly Postgres, give your database its own app name (I did my web app name + `-db`),
-		- **Make sure to pick the Development deployment option** ; default is production, which costs more
-	- Then confirm settings
-- This command will generate credentials for your Postgres cluster &mdash; **save these somewhere private in case you need them later**, as after you close this terminal window you'll never be able to get them again
-- If this worked, it'll create a Dockerfile and a fly.toml with your configuration settings for your web app; you won't need to run fly launch again
-	<!-- - Make sure listed port on previous web page is same as port in generated Dockerfile (`EXPOSE`) and fly.toml (`internal_port`); was done for me automatically -->
-- It will also deploy a Fly app for your Postgres cluster and create a database in your Postgres cluster with the same name as your web app name
-	- It will also make an environment variable called `DATABASE_URL` available to your Fly web app, which we'll use to connect to the Postgres database
-- Both of these apps will be visible on the Fly website on your dashboard
+To set up your deployed Postgres database for the deployed Fly web app, run `npm run setup`. This will connect to the deployed database and run the code in setup.sql.
 
-> You can also configure your web app and Postgres app separately by running `fly launch` to create your web app, `fly postgres create` to create a Postgres app, and `fly attach` to make the DATABASE_URL available to the web app; see [here](https://fly.io/docs/postgres/getting-started/create-pg-cluster/) for more details. I don't recommend doing this, as you have to do a little more work to get your web app and database app talking to each other.
+> If this doesn't work, if you're on Windows, try using Git Bash. If that still doesn't work, run `fly postgres connect -a YOURFLYPOSTGRESAPPNAME` (replacing `YOURFLYPOSTGRESAPPNAME` with your Fly **Postgres** app name) and manually copy-paste the code in setup.sql into the terminal.
 
-> `fly launch` won't generate a separate fly.toml for the Postgres app; if you want to tweak the Postgres settings, you need to run `fly config save --app FLYPOSTGRESAPPNAME` (replacing with your DB's app name) to create a fly.toml for the Postgres Fly app (make sure you run this in a different directory as this may overwrite the fly.toml for your web app; not sure, haven't checked).
+You'll use your local Postgres database for local testing. Run `npm run setup:local` to create the database and run setup.sql on it. If you run this again to clear your database and re-insert the dummy data, you'll see a "database already exists" error. Ignore this.
 
-Also, **any fly commands you run for Postgres app specifically will need to provide its app name through the command line**, since otherwise fly will use the app name in the fly.toml which is your web app, e.g. `fly postgres connect -a APPNAME`.
+You only need to run these setup scripts a) once at the beginning to create your database and tables and b) whenever you make a schema change or want to delete all existing data and start fresh.
 
-## Code changes you'll need to make web app work and connect to Postgres app
+## Running your app locally
 
-Your local and deployed server will need different configurations to run:
+To run your app locally, run `npm run start:local`. Visit `http://localhost:3000` (or whatever port you put in your server.js) to view the site.
 
-- Fly expects server to listen to host `0.0.0.0`, not `localhost`
-- Port can remain 3000 as long as you've configured Fly to deploy to that (see setup section above, should happen automatically when you run fly launch)
-- Fly will automatically put your DB credentials in the environment variable `DATABASE_URL` (you can access environment variables in the global Node object `process.env`); node-postgres can take a [connectionString](https://node-postgres.com/features/connecting#connection-uri) parameter when creating the pool, so we can pass DATABASE_URL to that, e.g. `let pool = new Pool({ connectionString: process.env.DATABASE_URL });`
-	- This means that you don't need to pass Postgres credentials to Fly, so it doesn't need access to your `.env` to run Postgres
-	- If you want to pass API keys to Fly, note that Fly includes `.env` in the `.dockerignore` file by default, which means any files named .env will be excluded from your deployed app code base. You can remove the .env line from .dockerignore, or just have a `keys.json` file that you .gitignore (but don't .dockerignore) and read from it like we've done before. You can also set secret env vars through the command line interface; see [here](https://fly.io/docs/rails/the-basics/configuration/).
-- To make your code work both locally and on Fly, you can do different things if `process.env.NODE_ENV === "production"`, because Fly sets NODE_ENV to production automatically, and otherwise it's the empty string by default; see server.js for details
+## Viewing/managing your deployed site
 
-### Using this repo
+Visit [https://fly.io/](https://fly.io/), click Dashboard, and select your Fly web app:
 
-If you use this repo, make the following changes:
+- The Hostname in the Application Information section is your web app's URL. It'll be `http:s//YOURFLYWEBAPPNAME.fly.dev`. Visit this URL to see your app.
+- In the sidebar (which will be on the bottom if your browser window is too small), select Live Logs. This will show you any console.logs printed by your server while you were viewing the Live Logs page (it won't show you historical logs). Visit your site's URL while this page is open to see some logs appear.
 
-1) Copy env.sample to .env and replace all variables with your local Postgres credentials
-2) Change .env's database name to match your Fly web app name
-	- Your .env is just for running locally, as Fly won't use this for Postgres, if your local database has the same name as your Fly database, it makes it easier to write a setup.sql that works for both; see below
-3) Change setup.sql's database name references to match your Fly web app name (to make it consistent with your local .env)
-4) In package.json, change FLYPOSTGRESAPPNAME to match your Fly Postgres app name
+To view all console.logs from your server (including historial logs), run `fly logs`. You'll need to quit this program with CTRL-c when you're done with it.
 
-To run your code locally:
+If you make changes to your code, to redeploy, run `fly deploy` (you won't need to run `fly launch` again).
 
-- `npm run setup:dev` to initialize your DB and tables - you only need to do this once (or whenever you change your schema/want to delete all data and start fresh)
-- `npm run start:dev` to run your server
+To open a psql terminal to your deployed database for debugging, run `fly postgres connect -a YOURFLYPOSTGRESAPPNAME -d YOURFLYPWEBAPPNAME`, replacing `YOURFLYPOSTGRESAPPNAME` with your Fly **Postgres** app name and `YOURFLYPWEBAPPNAME` with your Fly **web** app name. You can then run SQL queries like you would on your local database.
 
-To set up your Fly database:
+Fly shuts down your web app machine when it hasn't been used in awhile. This means the first visit to your page can load more slowly. You may also get database connection errors if it takes too long to wake up; refreshing the page after a few seconds usually fixes these.
 
-- `npm run setup`
+## Putting your own code in this project
 
-Fly will use the `npm run start` command automatically to start your server when you deploy. You shouldn't run `npm run start` locally if you're using Postgres, because the start command doesn't inject the Postgres environment variables that server.js expects to connect to the local DB.
+Copy-paste your server code into the indicated section in `app/server.js`. Don't change the code above and below it.
 
-## Creating your database tables
+Copy-paste your setup SQL into the indicated section in `setup.sql`. Don't change the code above and below it.
 
-- The Postgres Fly app's connection string in the DATABASE_URL assumes you're using a Fly database with the same name as your Fly web app
-- It's easiest to change your local database's name to match your Fly web app name (_not_ your Fly Postgres app name) in your setup.sql, e.g. if you named your Fly app `foo` and your Fly Postgres app `foo-db`, you'll run `CREATE DATABASE foo`
-	- You'll need to change the database name in any files that reference it, like .env/env.json, setup.sql, and if package.json uses the database name in any script commands, there as well
-- To run your setup.sql on the deployed Fly Postgres cluster, run `fly postgres connect -a FLYPOSTGRESAPPNAME < setup.sql` (or if you're using this repo, just run `npm run setup`), replacing FLYPOSTGRESAPPNAME with the name of your Fly Postgres app (I made mine the same as my webapp + `-db`); this will feed the SQL commands inside setup.sql to a SQL interpreter running on your Postgres instance, which will create the needed tables in your deployed database
-	- FYI, the DROP DATABASE command will probably say it failed with an error saying the database is currently in use, but the CREATE TABLE commands seem to work anyway, so don't worry about this
-	- You need to provide an explicit app name when running this command or else it'll use the one in your fly.toml, which is your web app's app name, not your Postgres app's app name
-	- You can also run `fly postgres connect -a FLYPOSTGRESAPPNAME` to open up a psql command line on your deployed DB and copy-paste the SQL commands in setup.sql manually if the above command doesn't work because you're not using a Unix shell; see docs [here](https://fly.io/docs/flyctl/postgres/)
+Move your client-side files into the `app/public` folder.
 
-## Deploy your web app
+Run `fly deploy` and visit your site's URL to see your site.
 
-Your Postgres app is already deployed, but we still need to deploy your web app.
+## When you're done with the project
 
-- Run `fly deploy` to actually deploy web app to public internet
-- Rerun `fly deploy` every time you change code to re-deploy it
-- Web app will be available at `https://FLYWEBAPPNAME.fly.dev/`
-- Can see server logs at `https://fly.io/apps/FLYWEBAPPNAME/monitoring` or by running `fly logs` from the command line
-- Can ssh into server with `fly ssh console`; note that this won't work if no instances of your web app are active, and Fly will automatically autoscale down to 0 instances if the site hasn't been used in a bit, so if this fails, make sure your deployment didn't crash, then visit your site's URL to start one of the machines and then it should work
-- Can run `fly postgres connect -a FLYPOSTGRESAPPNAME` to connect to your Postgres instance with a psql shell
+To save money, when you're done with this project, you'll want to delete your web and Postgres apps from Fly.
 
-It seems like sometimes the Fly Postgres app is slow to accept connections, so any code that touches the database might fail at first when you visit your website. Try again after a few seconds if you get a network error to see if it's started.
+Visit [https://fly.io/](https://fly.io/), click Dashboard, and select your Fly web app. Go to Settings and click Delete app. Go back to your Dashboard and do the same with your Fly Postgres app.
diff --git a/demo_fly_postgres/setup.sql b/demo_fly_postgres/setup.sql
index 5bae120f9617e9959dc7d6e8786cd0ca048ff78c..36d70250dc2c6ec90089f529960412ebc4e81738 100644
--- a/demo_fly_postgres/setup.sql
+++ b/demo_fly_postgres/setup.sql
@@ -1,7 +1,17 @@
-DROP DATABASE IF EXISTS FLYWEBAPPNAME;
-CREATE DATABASE FLYWEBAPPNAME;
-\c FLYWEBAPPNAME
+\c YOURFLYWEBAPPNAME
+
+-- use this to clear any existing tables to reinsert fresh data
+-- you'll need to add a DROP TABLE for every table you add
+-- we don't drop the database because that causes errors with fly
+DROP TABLE IF EXISTS foo;
+
+-- create whatever tables you need here
 CREATE TABLE foo (
 	id SERIAL PRIMARY KEY,
 	datum TEXT
 );
+
+-- dummy data
+INSERT INTO foo (datum) VALUES ("Hello this is some text");
+INSERT INTO foo (datum) VALUES ("Another sentence");
+INSERT INTO foo (datum) VALUES ("What's up?");
diff --git a/readme.md b/readme.md
index 124eda6243079db3066521a33200e1ed0a7fdc9b..1257c2e6203d628a95db6c2c4cdbeccd86151819 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,12 @@
 
 # CS375 demos
 
-See the readme.md in each folder for information about the demo.
+Each folder contains sample code covering different topics:
+
+- demo_fly_postgres: Deploying a simple web app and Postgres app to the public internet using Fly.
+- demo_front-end_cookies: Server which sets and checks cookies.
+- demo_password_cookies: Server that stores hashed passwords in a database, checks them when logging, and sets a randomized token cookie.
+- demo_ssr: Server that does server-side rendering using the EJS package.
+- demo_websockets: Simple client-server websockets code.
+
+See the readme.md in each folder for more information.