This repository has been archived by the owner on Mar 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Cleanup secret using limited charset feature * More details in README * Add button to launch example app * Use acorn.io in Button * Use simple counter app as an example
- Loading branch information
Showing
13 changed files
with
234 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,76 @@ | ||
# Postgres | ||
## Postgres Database | ||
|
||
This Acorn provides a Postgres database as an Acorn Service. This Acorn can be used to create a database for your application during development. It runs a single Postgres container backed by a persistent volume. | ||
PostgreSQL is an open-source object-relational database system that uses and extends the SQL language. Known for its robustness and reliability, it supports advanced data types and advanced performance optimization, offering features like complex queries, atomic transactions, and concurrent connections. | ||
|
||
A default user is automatically generated during the creation process. | ||
## Postgres as an Acorn Service | ||
|
||
This Acorn provides a Postgres database as an Acorn Service. It can be used to easily get a Postgres database for your application during development. The current service runs a single Postgres container backed by a persistent volume and define credentials for an admin user. | ||
|
||
This Postgres instance: | ||
- is backed by a persistent volume | ||
- generate credentials for an admin user | ||
|
||
The Acorn image of this service is hosted in GitHub container registry at [ghcr.io/acorn-io/postgres](ghcr.io/acorn-io/postgres). | ||
|
||
Currently this Acorn has the following configuration options: | ||
- *dbName*: name of the database (*postgres* by default) | ||
- *dbUser*: name of the admin user (*postgres* by default) | ||
|
||
## Usage | ||
|
||
The [examples folder](https://github.com/acorn-io/postgres/tree/main/examples) contains a sample application using this Service. This app consists in a Python backend based on the FastAPI library, it displays a web page indicating the number of times the application was called, a counter is saved in the underlying Postgres database and incremented with each request. The screenshot below shows the UI of the example application. | ||
|
||
![UI](./examples/images/ui.png) | ||
|
||
To use the Postgres Service, we first define a *service* property in the Acornfile of the example app: | ||
|
||
``` | ||
services: db: image: "ghcr.io/acorn-io/postgres:v#.#-#" | ||
``` | ||
|
||
Next we define the application container: | ||
|
||
``` | ||
containers: app: { | ||
build: { | ||
context: "." | ||
target: "dev" | ||
} | ||
consumes: ["db"] | ||
ports: publish: "8000/http" | ||
env: { | ||
POSTGRES_HOST: "@{service.db.address}" | ||
POSTGRES_DB: "@{service.db.data.dbName}" | ||
POSTGRES_USER: "@{service.db.secrets.admin.username}" | ||
POSTGRES_PASSWORD: "@{service.db.secrets.admin.password}" | ||
} | ||
} | ||
``` | ||
|
||
This container is built using the Dockerfile in the examples folder. Once built, the container consumes the Postgres service using properties provided by the service: | ||
- @{service.db.address} : URL to connect to the postgres service | ||
- @{service.db.data.dbName}: database name | ||
- @{service.db.secrets.admin.username}: username of the admin user | ||
- @{service.db.secrets.admin.password}: password of the admin user | ||
|
||
This example can be run with the following command (to be run from the *examples* folder) | ||
|
||
``` | ||
acorn run -n app | ||
``` | ||
|
||
After a few tens of seconds an http endpoint will be returned. Using this endpoint we can access the application and see the counter incremented on each reload of the page. | ||
|
||
Once we're done, we can remove the app: | ||
|
||
``` | ||
acorn rm -af app | ||
``` | ||
|
||
## Deploy the app to your Acorn Sandbox | ||
|
||
Instead of managing your own Acorn installation, you can deploy this application in the Acorn Sandbox, the free SaaS offering provided by Acorn. Access to the sandbox requires only a GitHub account, which is used for authentication. | ||
|
||
[![Run in Acorn](https://acorn.io/v1-ui/run/badge?image=ghcr.io+acorn-io+postgres+examples:v%23.%23-%23)](https://acorn.io/run/ghcr.io/acorn-io/postgres/examples:v%23.%23-%23) | ||
|
||
An application running in the Sandbox will automatically shut down after 2 hours, but you can use the Acorn Pro plan to remove the time limit and gain additional functionalities. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
FROM python:3.9 as base | ||
WORKDIR /app | ||
|
||
FROM base as build | ||
COPY requirements.txt requirements.txt | ||
RUN pip install --no-cache-dir --upgrade -r requirements.txt | ||
COPY . . | ||
|
||
FROM build as dev | ||
EXPOSE 8000 | ||
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000", "--proxy-headers"] | ||
|
||
FROM build as production | ||
EXPOSE 8000 | ||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
from fastapi import FastAPI, Request | ||
from fastapi.responses import HTMLResponse | ||
from fastapi.staticfiles import StaticFiles | ||
from fastapi.templating import Jinja2Templates | ||
import os | ||
import psycopg2 | ||
|
||
# Configuration | ||
POSTGRES_HOST = os.environ.get('POSTGRES_HOST') | ||
POSTGRES_DB = os.environ.get('POSTGRES_DB') | ||
POSTGRES_USER = os.environ.get('POSTGRES_USER') | ||
POSTGRES_PASSWORD = os.environ.get('POSTGRES_PASSWORD') | ||
|
||
# FastAPI application | ||
app = FastAPI() | ||
app.mount("/static", StaticFiles(directory="static"), name="static") | ||
templates = Jinja2Templates(directory="templates") | ||
|
||
def get_db_connection(): | ||
conn = psycopg2.connect( | ||
user=POSTGRES_USER, | ||
password=POSTGRES_PASSWORD, | ||
host=POSTGRES_HOST, | ||
database=POSTGRES_DB | ||
) | ||
return conn | ||
|
||
def setup_database(): | ||
# Establishing a new connection to our database | ||
conn = get_db_connection() | ||
try: | ||
with conn.cursor() as cursor: | ||
# Create table if it doesn't exist | ||
cursor.execute(""" | ||
CREATE TABLE IF NOT EXISTS visit_counter ( | ||
counter_name VARCHAR PRIMARY KEY, | ||
count_value INT NOT NULL | ||
); | ||
""") | ||
# Initialize the counter if it doesn't exist | ||
cursor.execute(""" | ||
INSERT INTO visit_counter (counter_name, count_value) | ||
VALUES ('hits', 0) | ||
ON CONFLICT (counter_name) DO NOTHING; | ||
""") | ||
# Committing any changes and closing the transaction | ||
conn.commit() | ||
finally: | ||
# Closing the database connection | ||
conn.close() | ||
|
||
@app.on_event("startup") | ||
async def startup_event(): | ||
# Setting up database during startup | ||
setup_database() | ||
|
||
@app.get('/', response_class=HTMLResponse) | ||
async def read_root(request: Request): | ||
# Each request gets a new database connection | ||
conn = get_db_connection() | ||
try: | ||
with conn.cursor() as cursor: | ||
# Increment the counter and retrieve its value | ||
cursor.execute("UPDATE visit_counter SET count_value = count_value + 1 WHERE counter_name = 'hits';") | ||
cursor.execute("SELECT count_value FROM visit_counter WHERE counter_name = 'hits';") | ||
count = cursor.fetchone()[0] | ||
# Committing the update | ||
conn.commit() | ||
finally: | ||
# Closing the connection | ||
conn.close() | ||
|
||
# Returning the current counter value within the rendered HTML | ||
return templates.TemplateResponse("index.html", {"request": request, "counter": count}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
fastapi == 0.101.0 | ||
uvicorn[standard] == 0.23.2 | ||
psycopg2-binary == 2.9.9 | ||
Jinja2 == 3.1.2 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
html, body { | ||
height: 100%; | ||
margin: 0; | ||
padding: 0; | ||
background: #483285; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
text-align: center; | ||
color: white; | ||
font-family: Arial, sans-serif; | ||
} | ||
.content { | ||
width: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
img { | ||
width: 100%; | ||
max-width: 100%; | ||
height: auto; | ||
margin-bottom: 20px; | ||
} | ||
.counter { | ||
font-size: 4rem; | ||
width: 100%; | ||
margin-top: 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Stylish Counter</title> | ||
<link href="/static/style.css" rel="stylesheet"> | ||
</head> | ||
<body> | ||
<div class="content"> | ||
<img src="/static/acorn.png" alt="Acorn logo" /> | ||
<div class="counter">Page views: {{counter}}</div> | ||
</div> | ||
</body> | ||
</html> |
This file was deleted.
Oops, something went wrong.