Compare commits
3 commits
a3b201fa09
...
97e21bcb9b
| Author | SHA1 | Date | |
|---|---|---|---|
| 97e21bcb9b | |||
| f4c7f4dfc2 | |||
| fb2c6368d8 |
4 changed files with 87 additions and 7 deletions
|
|
@ -47,7 +47,8 @@ jobs:
|
|||
run: |
|
||||
. "$HOME/.cargo/env"
|
||||
cargo build --release --locked
|
||||
mv target/release/upvoters upvoters-linux-x86_64
|
||||
mkdir -p dist/release
|
||||
mv target/release/upvoters dist/release/upvoters-linux-x86_64
|
||||
|
||||
- name: Create release
|
||||
uses: https://data.forgejo.org/actions/forgejo-release@v2
|
||||
|
|
@ -55,5 +56,4 @@ jobs:
|
|||
direction: upload
|
||||
tag: ${{ github.ref_name }}
|
||||
release-notes: "Release ${{ github.ref_name }}"
|
||||
files: upvoters-linux-x86_64
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1962,7 +1962,7 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|||
|
||||
[[package]]
|
||||
name = "upvoters"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "upvoters"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
|
||||
|
|
|
|||
86
README.md
86
README.md
|
|
@ -6,11 +6,16 @@ I came across the [creator's (Herman Martinus) blogging site](https://herman.bea
|
|||
I wanted something similar and decided to implement it myself.
|
||||
The goal is maximum simplicity.
|
||||
|
||||
## Important Notes
|
||||
|
||||
This service does NOT have any authentication/authorization, so you should NOT serve this to the public web.
|
||||
I'm using this by just serving it on the same VPS as my blog.
|
||||
## Table of Contents
|
||||
|
||||
- [Requirements](#requirements)
|
||||
- [Configuration](#configuration)
|
||||
- [Running locally](#running-locally)
|
||||
- [API](#api)
|
||||
- [Running tests](#running-tests)
|
||||
- [Actual deployment](#actual-deployment)
|
||||
- [License](#license)
|
||||
|
||||
## Requirements
|
||||
|
||||
|
|
@ -24,6 +29,8 @@ The following environment variables are required:
|
|||
| Variable | Description |
|
||||
|------------------------------|----------------------------------------------------------------------------------------|
|
||||
| `POSTGRES_CONNECTION_STRING` | PostgreSQL connection string (e.g. `postgres://user:password@localhost:5432/upvoters`) |
|
||||
| `ALLOWED_ORIGINS` | Comma-separated list of allowed CORS origins (e.g. `localhost:1313,example.com`) |
|
||||
| `PORT` | Port to listen on (default: `3000`) |
|
||||
|
||||
## Running locally
|
||||
|
||||
|
|
@ -81,6 +88,79 @@ Tests require a running PostgreSQL instance at `postgres://uprs:password123@loca
|
|||
cargo test
|
||||
```
|
||||
|
||||
## Actual deployment
|
||||
|
||||
Here are the instructions for how I deployed this service. You might be able to just run it through the docker-compose on a VPS but I already had a postgres server set up:
|
||||
|
||||
1. Install dependencies (rust/postgres) (For debian server).
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y postgresql postgresql-contrib
|
||||
```
|
||||
2. Create `postgres` user to manage postgres and `upvoters` user to run the app:
|
||||
```bash
|
||||
# Create the system user that will run the app
|
||||
sudo useradd --system --home /opt/upvoters --create-home upvoters
|
||||
|
||||
# Create the PostgreSQL role with peer auth (no password needed)
|
||||
sudo -u postgres psql -c "CREATE USER upvoters;"
|
||||
sudo -u postgres psql -c "CREATE DATABASE upvoters OWNER upvoters;"
|
||||
|
||||
# Enable peer auth for the upvoters role (append to pg_hba.conf)
|
||||
echo "local upvoters upvoters peer" | sudo tee -a /etc/postgresql/16/main/pg_hba.conf
|
||||
sudo systemctl reload postgresql
|
||||
```
|
||||
3. Create the votes table as the `upvoters` user
|
||||
```bash
|
||||
sudo -u upvoters psql upvoters
|
||||
```
|
||||
```sql
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS votes (
|
||||
slug text not null,
|
||||
voter_id uuid not null,
|
||||
created_at timestamptz NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||
primary key (slug, voter_id)
|
||||
);
|
||||
```
|
||||
4. Download the binary (You can also install rust and build yourself if you prefer). Replace `v0.2.0` with the latest release tag.
|
||||
```bash
|
||||
sudo curl https://forge.alexselimov.com/aselimov/upvoters/releases/download/v0.2.0/upvoters-linux-x86_64 --output /opt/upvoters/upvoters
|
||||
sudo chmod +x /opt/upvoters/upvoters
|
||||
sudo chown upvoters /opt/upvoters/upvoters
|
||||
```
|
||||
5. Create a systemd service at /etc/systemd/system/upvoters.service
|
||||
```
|
||||
[Unit]
|
||||
Description=upvoters rust backend
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
User=upvoters
|
||||
Group=upvoters
|
||||
WorkingDirectory=/opt/upvoters
|
||||
ExecStart=/opt/upvoters/upvoters
|
||||
Restart=on-failure
|
||||
# The below connection string works if you have peer auth enabled and have postgresql running on
|
||||
# a socket
|
||||
Environment='POSTGRES_CONNECTION_STRING=postgresql:///upvoters?host=/var/run/postgresql'
|
||||
Environment='ALLOWED_ORIGINS=https://example.com'
|
||||
# Specify a PORT if the default 3000 is already taken
|
||||
Environment='PORT=3000'
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
6. Enable and start the service
|
||||
```bash
|
||||
sudo systemctl enable --now upvoters
|
||||
```
|
||||
7. Test from VPS using curl
|
||||
```bash
|
||||
curl https://example.com/api/posts/tests/votes
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT — see [LICENSE](LICENSE).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue