This app ships a single Docker Compose stack designed to run on any Linux VM with Docker + Docker Compose v2 installed. The same commands apply on DigitalOcean, Hetzner, Linode/Akamai, AWS Lightsail/EC2, or any other Docker-capable host.
On a fresh VM with Docker + Compose installed (see these quick-start guides for various hosting services), just run:
APP_HOST=your.domain.or.ip /bin/bash -c "$(curl -fsSL https://posseparty.com/setup.sh)"There are a number of env vars to consider, but the two you might want to set before running the above command are:
APP_HOSTsets the public host for HTTPS via Caddy/Let’s Encrypt and Rails URL helpers (IP addresses are OK, e.g.,192.168.1.24). If omitted, Caddy still serves plain HTTP on :80 (IP access).APP_PRIVATE_HOST(defaults tofalse) when true, Caddy skips public ACME certificates and uses an internal CA for TLS, and Rails will assume HTTPS is supported but will not force HTTPS unless you explicitly setFORCE_SSL=true.
- web: Rails app (Puma) with static assets served in-container.
- worker: Solid Queue via
./script/worker. - db: Postgres with healthcheck and a persisted
db_datavolume. - proxy: TLS-terminating reverse proxy on 80/443, proxying to
web:3000forAPP_HOST. - migrate: one-shot
./script/release(runs Rails migrations) that must succeed before other services start.
All of this is defined in docker-compose.yml and wired so that web/worker wait for a healthy database and successful migrations before booting.
- Create a Droplet from the Docker Marketplace image
- SSH (
ssh root@ip). - Follow “One-time setup”.
- Create a server using the Docker CE app image (Ubuntu with Docker + Compose).
- SSH (
ssh root@ip). - Run the setup commands.
- Use the Docker Marketplace app or install Docker + Compose plugin on Ubuntu (
sudo apt install docker-compose-plugin). - SSH (
ssh root@ip). - Run the setup commands.
- Launch Ubuntu 22.04/24.04.
- Install Docker and the Compose plugin using the official Linux instructions.
- SSH (
ssh ubuntu@ip). - Run the setup commands.
If Docker Engine and the docker compose plugin are present, the same setup.sh → bin/start flow works.
POSSE Party is configured via environment variables, which can be edited on your server using whatever text editor is available in the .env file. If you ran the above setup command, it will be in a subdirectory named posse_party
nano posse_party/.envVariables you might be interested in setting:
APP_HOST- hostname (myapp.posseparty.com) or IP address (192.168.1.24). If this isn't set, the app won't be able to generate full URLs, which are needed for transactional emails and OAuth authorization flows (e.g., LinkedIn, YouTube)APP_HTTP_PORT— host port to expose HTTP for the app (maps to container port 80, defaults to80)APP_HTTPS_PORT— host port to expose HTTPS for the app (maps to container port 443, defaults to443)APP_PRIVATE_HOST— set totruewhen deploying to a private hostname/IP so Caddy skips public ACME cert attempts and uses an internal TLS certificate; Rails will generatehttps://URLs for that host but will not force HTTPS redirects unless you explicitly setFORCE_SSL=true.FORCE_SSL— redirects HTTP requests to HTTPS. When unset/blank, it defaults totruefor public HTTPS hosts andfalsewhenAPP_PRIVATE_HOST=trueor HTTPS is not configured.RAILS_ASSET_HOST— CDN host for static assets (e.g.,https://cdn.example.com)SECRET_KEY_BASE(set by default withopenssl rand -hex 64)- Email delivery is optional, but required to send login and transactional emails:
MAIL_PROVIDERone of:amazon_ses,resend,mailgun,postmark,sendgrid,brevo,mailjet,smtp. Each requires a different set of environment variables to be configured (see docs/mail.md for details)MAIL_FROM_ADDRESS(e.g.possy@possyparty.com)
Whenever you change these settings, you'll need to restart the server, which you can do by running:
./posse_party/bin/restart
For your convenience, POSSE Party's setup command leaves behind a handful of scripts for managing your install.
You'll find these scripts wherever you ran the setup script in a posse_party subdirectory, so you may need to first change to that directory:
cd posse_party./bin/start./bin/stop./bin/upgradeYou can run the production Rails console with bin/console:
./bin/consoleThe Postgres CLI is available via bin/psql (any args will be forwarded):
./bin/psqlYou can also tail the production server logs with bin/log. By default, this will pass -n 200 -f, but you can pass your own arguments to override that:
./bin/log./bin/backupUnless an argument is specified, a timestamped SQL backup will be saved to backups/.
./bin/stop
# Will ask you to confirm, pass --confirm to override:
./bin/drop_database
./bin/restore backups/2025-12-25-12-00-00-posse-party-backup.sql
./bin/startOn my Mac, I have a nightly backup job that runs this script, which lives ~bin/backup_posse_party. My backup disk is named after the Orlando Magic mascot, Stuff:
#!/usr/bin/env bash
set -euo pipefail
REMOTE_USER="possy"
REMOTE_HOST="app.posseparty.com"
REMOTE_ADDRESS="${REMOTE_USER}@${REMOTE_HOST}"
REMOTE_DIRECTORY="~/posse_party"
LOCAL_DIRECTORY="${1:-/Volumes/stuff/backups/posse_party}"
echo "Running backup of POSSE Party database"
ssh "$REMOTE_ADDRESS" "cd $REMOTE_DIRECTORY && ./bin/backup"
echo "Syncing backups of POSSE Party database"
mkdir -p "$LOCAL_DIRECTORY/database"
rsync -av --ignore-existing "$REMOTE_ADDRESS:$REMOTE_DIRECTORY/backups/" "$LOCAL_DIRECTORY/database"By default, POSSE Party will only be updated to the latest version if you SSH into your server and run:
cd posse_party
./bin/upgradeIf you'd prefer to automatically fetch and deploy the latest release, here are a couple options.
On most modern Linux distributions (Ubuntu, Debian, etc.), you can use a systemd timer to run the upgrade script at a fixed time each day.
Find the full directory where POSSE Party is installed:
cd posse_party
pwdNote the full path printed by pwd; you will use it below.
Create a systemd service that runs the upgrade script. As root:
sudo nano /etc/systemd/system/posse-party-upgrade.servicePaste the following, replacing /path/to/posse_party with the directory you found above:
[Unit]
Description=POSSE Party upgrade
[Service]
Type=oneshot
WorkingDirectory=/path/to/posse_party
ExecStart=/usr/bin/env bash -lc './bin/upgrade'Create a timer that runs once per night (below, we set it for 03:30 server time):
sudo nano /etc/systemd/system/posse-party-upgrade.timerPaste:
[Unit]
Description=Run POSSE Party upgrade nightly
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.targetReload systemd and enable the timer:
sudo systemctl daemon-reload
sudo systemctl enable --now posse-party-upgrade.timerYou can verify it is scheduled with:
systemctl list-timers | grep posse-party-upgradeTo disable automatic upgrades later:
sudo systemctl disable --now posse-party-upgrade.timerIf your server does not use systemd, you can run the upgrade once a night using cron.
Edit the crontab for the user that owns the POSSE Party install:
crontab -eAdd a line like this, adjusting /path/to/posse_party if needed:
0 3 * * * cd /path/to/posse_party && ./bin/upgrade >> ~/posse_party_upgrade.log 2>&1This will attempt an upgrade every day at 03:00 and append output to ~/posse_party_upgrade.log.
Before turning on automatic upgrades, make sure your backups are working (for example, using the backup automation from the previous section), so you can roll back if something goes wrong.
If you find yourself stuck and just want a fresh start, here's how to do it:
To recreate containers without wiping data:
cd posse_party
docker compose down
docker volume rm posse_party_proxy_data # Resets TLS/SSL cache
docker compose up -dTo start over completely, deleting your database before recreating the containers:
cd posse_party
docker compose down -v
cd ..
rm -rf posse_party
APP_HOST=your.domain.or.ip /bin/bash -c "$(curl -fsSL https://posseparty.com/setup.sh)"