Init
This commit is contained in:
commit
94fb270008
22 changed files with 2424 additions and 0 deletions
33
.editorconfig
Normal file
33
.editorconfig
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*.rs]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.sql]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.sql]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.html]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
2
.env
Normal file
2
.env
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
POSTGRES_USER="blog"
|
||||||
|
POSTGRES_PASSWORD="blog"
|
2
.env.example
Normal file
2
.env.example
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
POSTGRES_USER="blog"
|
||||||
|
POSTGRES_PASSWORD="blog"
|
6
Makefile
Normal file
6
Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.PHONY: all build
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
BUILDKIT_PROGRESS=plain docker compose build
|
7
backend/.dockerignore
Normal file
7
backend/.dockerignore
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/target
|
||||||
|
|
||||||
|
Dockerfile
|
||||||
|
.gitignore
|
||||||
|
.dockerignore
|
||||||
|
vendor/
|
||||||
|
example/
|
1
backend/.gitignore
vendored
Normal file
1
backend/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
1862
backend/Cargo.lock
generated
Normal file
1862
backend/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
37
backend/Cargo.toml
Normal file
37
backend/Cargo.toml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[package]
|
||||||
|
name = "backend"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
authors = ["Dominic Grimm <dominic@dergrimm.net>"]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "backend"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "blogctl"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
lto = "fat"
|
||||||
|
strip = true
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
actix-web = "4.3.0"
|
||||||
|
anyhow = { version = "1.0.69", features = ["backtrace"] }
|
||||||
|
chrono = { version = "0.4.23", features = ["serde"] }
|
||||||
|
clap = { version = "4.1.4", features = ["derive"] }
|
||||||
|
diesel = { version = "2.0.2", features = ["i-implement-a-third-party-backend-and-opt-into-breaking-changes", "postgres", "chrono", "r2d2"] }
|
||||||
|
env_logger = "0.10.0"
|
||||||
|
envconfig = "0.10.0"
|
||||||
|
fronma = "0.1.1"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
log = "0.4.17"
|
||||||
|
scan_dir = "0.3.3"
|
||||||
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
|
serde_yaml = "0.9.17"
|
||||||
|
|
||||||
|
[target.'cfg(not(target_env = "msvc"))'.dependencies]
|
||||||
|
tikv-jemallocator = "0.5.0"
|
36
backend/Dockerfile
Normal file
36
backend/Dockerfile
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
FROM docker.io/lukemathwalker/cargo-chef:latest-rust-1.67.0 as chef
|
||||||
|
|
||||||
|
FROM chef as diesel
|
||||||
|
RUN cargo install diesel_cli --no-default-features --features postgres
|
||||||
|
|
||||||
|
FROM chef as planner
|
||||||
|
WORKDIR /usr/src/backend
|
||||||
|
RUN mkdir src && touch src/main.rs
|
||||||
|
COPY ./Cargo.toml ./Cargo.lock ./
|
||||||
|
RUN cargo chef prepare --recipe-path recipe.json
|
||||||
|
|
||||||
|
FROM chef as builder
|
||||||
|
WORKDIR /usr/src/backend
|
||||||
|
COPY --from=planner /usr/src/backend/recipe.json .
|
||||||
|
RUN cargo chef cook --release --recipe-path recipe.json
|
||||||
|
RUN rm -rf ./src
|
||||||
|
COPY ./src ./src
|
||||||
|
RUN cargo build --release
|
||||||
|
|
||||||
|
FROM docker.io/debian:bullseye-slim as runner
|
||||||
|
RUN apt update
|
||||||
|
RUN apt install -y libpq5
|
||||||
|
RUN apt install -y ca-certificates
|
||||||
|
RUN apt-get clean
|
||||||
|
RUN apt-get autoremove -y
|
||||||
|
RUN rm -rf /var/lib/{apt,dpkg,cache,log}/
|
||||||
|
WORKDIR /usr/local/bin
|
||||||
|
ENV RUST_BACKTRACE=full
|
||||||
|
COPY --from=diesel /usr/local/cargo/bin/diesel .
|
||||||
|
WORKDIR /usr/src/backend
|
||||||
|
COPY ./run.sh .
|
||||||
|
RUN chmod +x ./run.sh
|
||||||
|
COPY ./migrations ./migrations
|
||||||
|
COPY --from=builder /usr/src/backend/target/release/backend /usr/src/backend/target/release/blogctl ./bin/
|
||||||
|
EXPOSE 80
|
||||||
|
ENTRYPOINT [ "./run.sh" ]
|
7
backend/migrations/2023-02-06-134456_init/down.sql
Normal file
7
backend/migrations/2023-02-06-134456_init/down.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
DROP TABLE posts;
|
||||||
|
|
||||||
|
DROP TABLE tags;
|
||||||
|
|
||||||
|
DROP INDEX configs_active;
|
||||||
|
|
||||||
|
DROP TABLE configs;
|
49
backend/migrations/2023-02-06-134456_init/up.sql
Normal file
49
backend/migrations/2023-02-06-134456_init/up.sql
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
CREATE TABLE configs(
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
active BOOLEAN NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
copyright TEXT NOT NULL,
|
||||||
|
owner_name TEXT NOT NULL,
|
||||||
|
owner_email TEXT NOT NULL,
|
||||||
|
owner_website TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX configs_active ON configs(active)
|
||||||
|
WHERE
|
||||||
|
active;
|
||||||
|
|
||||||
|
INSERT INTO
|
||||||
|
configs(
|
||||||
|
active,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
copyright,
|
||||||
|
owner_name,
|
||||||
|
owner_email
|
||||||
|
)
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
TRUE,
|
||||||
|
'generic blog',
|
||||||
|
'just a generic blog',
|
||||||
|
'(C) just a generic blog',
|
||||||
|
'generic blog owner',
|
||||||
|
'blog@example.com'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tags(
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name TEXT UNIQUE NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE posts(
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
slug TEXT UNIQUE NOT NULL,
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
published_at DATE NOT NULL,
|
||||||
|
edited_at DATE,
|
||||||
|
active BOOLEAN NOT NULL
|
||||||
|
);
|
7
backend/run.sh
Normal file
7
backend/run.sh
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
DATABASE_URL="$BACKEND_DB_URL" diesel setup \
|
||||||
|
--migration-dir ./migrations \
|
||||||
|
--locked-schema &&
|
||||||
|
./bin/backend run
|
46
backend/src/bin/backend.rs
Normal file
46
backend/src/bin/backend.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#[cfg(not(target_env = "msvc"))]
|
||||||
|
use tikv_jemallocator::Jemalloc;
|
||||||
|
|
||||||
|
#[cfg(not(target_env = "msvc"))]
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: Jemalloc = Jemalloc;
|
||||||
|
|
||||||
|
use actix_web::{
|
||||||
|
http::header,
|
||||||
|
middleware,
|
||||||
|
web::{self, Data},
|
||||||
|
App, Error, HttpResponse, HttpServer,
|
||||||
|
};
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
|
use backend::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
#[clap(author, version, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
commands: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
#[clap(about = "Starts webserver")]
|
||||||
|
Run,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
match Cli::parse().commands {
|
||||||
|
Commands::Run => {
|
||||||
|
std::env::set_var("RUST_LOG", "info");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let server = HttpServer::new(move || {
|
||||||
|
App::new()
|
||||||
|
.wrap(middleware::Compress::default())
|
||||||
|
.wrap(middleware::Logger::default())
|
||||||
|
});
|
||||||
|
server.bind("0.0.0.0:80").unwrap().run().await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
127
backend/src/bin/blogctl.rs
Normal file
127
backend/src/bin/blogctl.rs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
#[cfg(not(target_env = "msvc"))]
|
||||||
|
use tikv_jemallocator::Jemalloc;
|
||||||
|
|
||||||
|
#[cfg(not(target_env = "msvc"))]
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: Jemalloc = Jemalloc;
|
||||||
|
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
use chrono::prelude::*;
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use scan_dir::ScanDir;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use backend::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
#[clap(author, version, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
commands: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
#[clap(about = "Imports new posts")]
|
||||||
|
Import,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Blog {
|
||||||
|
name: String,
|
||||||
|
description: String,
|
||||||
|
copyright: String,
|
||||||
|
owner: BlogOwner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct BlogOwner {
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
website: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct PostFrontmatter {
|
||||||
|
name: String,
|
||||||
|
slug: String,
|
||||||
|
description: String,
|
||||||
|
published_at: NaiveDate,
|
||||||
|
edited_at: Option<NaiveDate>,
|
||||||
|
active: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Post {
|
||||||
|
frontmatter: PostFrontmatter,
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
match Cli::parse().commands {
|
||||||
|
Commands::Import => {
|
||||||
|
let conn = &mut db::establish_connection()?;
|
||||||
|
|
||||||
|
let blog: Blog = serde_yaml::from_str(&fs::read_to_string("/blog/blog.yml")?)?;
|
||||||
|
|
||||||
|
diesel::delete(db::schema::configs::table)
|
||||||
|
.filter(db::schema::configs::active.eq(true))
|
||||||
|
.execute(conn)?;
|
||||||
|
diesel::insert_into(db::schema::configs::table)
|
||||||
|
.values(db::models::NewConfig {
|
||||||
|
active: true,
|
||||||
|
name: &blog.name,
|
||||||
|
description: &blog.description,
|
||||||
|
copyright: &blog.copyright,
|
||||||
|
owner_name: &blog.owner.name,
|
||||||
|
owner_email: &blog.owner.email,
|
||||||
|
owner_website: blog.owner.website.as_deref(),
|
||||||
|
})
|
||||||
|
.execute(conn)?;
|
||||||
|
|
||||||
|
let posts = ScanDir::dirs().read("/blog/posts", |iter| {
|
||||||
|
iter.map(|(entry, name)| {
|
||||||
|
dbg!(&entry, &name);
|
||||||
|
let src = fs::read_to_string(entry.path().join("post.md"))?;
|
||||||
|
let frontmatter = match fronma::parser::parse::<PostFrontmatter>(&src) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(x) => bail!("Error parsing frontmatter: {:?}", x),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Post {
|
||||||
|
frontmatter: PostFrontmatter {
|
||||||
|
name: frontmatter.headers.name.trim().to_string(),
|
||||||
|
slug: frontmatter.headers.slug.trim().to_string(),
|
||||||
|
description: frontmatter.headers.description.trim().to_string(),
|
||||||
|
..frontmatter.headers
|
||||||
|
},
|
||||||
|
content: frontmatter.body.trim().to_string(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>>>()
|
||||||
|
})??;
|
||||||
|
dbg!(&posts);
|
||||||
|
|
||||||
|
for post in posts {
|
||||||
|
diesel::delete(db::schema::posts::table)
|
||||||
|
.filter(db::schema::posts::slug.eq(&post.frontmatter.slug))
|
||||||
|
.execute(conn)?;
|
||||||
|
diesel::insert_into(db::schema::posts::table)
|
||||||
|
.values(db::models::NewPost {
|
||||||
|
name: &post.frontmatter.name,
|
||||||
|
slug: &post.frontmatter.slug,
|
||||||
|
description: &post.frontmatter.description,
|
||||||
|
content: &post.content,
|
||||||
|
published_at: post.frontmatter.published_at,
|
||||||
|
edited_at: post.frontmatter.edited_at,
|
||||||
|
active: post.frontmatter.active,
|
||||||
|
})
|
||||||
|
.execute(conn)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
backend/src/config.rs
Normal file
13
backend/src/config.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
use envconfig::Envconfig;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
#[derive(Envconfig, Debug)]
|
||||||
|
pub struct Config {
|
||||||
|
#[envconfig(from = "BACKEND_DB_URL")]
|
||||||
|
pub db_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref CONFIG: Config = Config::init_from_env().unwrap();
|
||||||
|
}
|
28
backend/src/db/mod.rs
Normal file
28
backend/src/db/mod.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use diesel::pg::PgConnection;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::r2d2::{ConnectionManager, Pool};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use crate::config;
|
||||||
|
|
||||||
|
pub mod models;
|
||||||
|
pub mod schema;
|
||||||
|
|
||||||
|
pub type DbPool = Pool<ConnectionManager<PgConnection>>;
|
||||||
|
|
||||||
|
pub fn establish_connection() -> ConnectionResult<PgConnection> {
|
||||||
|
PgConnection::establish(&config::CONFIG.db_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pool() -> Result<DbPool> {
|
||||||
|
Ok(
|
||||||
|
Pool::builder().build(ConnectionManager::<PgConnection>::new(
|
||||||
|
&config::CONFIG.db_url,
|
||||||
|
))?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref POOL: DbPool = pool().unwrap();
|
||||||
|
}
|
67
backend/src/db/models.rs
Normal file
67
backend/src/db/models.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
use chrono::prelude::*;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
|
||||||
|
use crate::db::schema;
|
||||||
|
|
||||||
|
#[derive(Identifiable, Queryable, Debug)]
|
||||||
|
#[diesel(table_name = schema::configs)]
|
||||||
|
pub struct Config {
|
||||||
|
pub id: i32,
|
||||||
|
pub active: bool,
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub copyright: String,
|
||||||
|
pub owner_name: String,
|
||||||
|
pub owner_email: String,
|
||||||
|
pub owner_website: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, Debug)]
|
||||||
|
#[diesel(table_name = schema::configs)]
|
||||||
|
pub struct NewConfig<'a> {
|
||||||
|
pub active: bool,
|
||||||
|
pub name: &'a str,
|
||||||
|
pub description: &'a str,
|
||||||
|
pub copyright: &'a str,
|
||||||
|
pub owner_name: &'a str,
|
||||||
|
pub owner_email: &'a str,
|
||||||
|
pub owner_website: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Identifiable, Queryable, Debug)]
|
||||||
|
#[diesel(table_name = schema::tags)]
|
||||||
|
pub struct Tag {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, Debug)]
|
||||||
|
#[diesel(table_name = schema::tags)]
|
||||||
|
pub struct NewTag<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Identifiable, Queryable, Debug)]
|
||||||
|
#[diesel(table_name = schema::posts)]
|
||||||
|
pub struct Post {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
pub slug: String,
|
||||||
|
pub description: String,
|
||||||
|
pub content: String,
|
||||||
|
pub published_at: NaiveDate,
|
||||||
|
pub edited_at: Option<NaiveDate>,
|
||||||
|
pub active: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, Debug)]
|
||||||
|
#[diesel(table_name = schema::posts)]
|
||||||
|
pub struct NewPost<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub slug: &'a str,
|
||||||
|
pub description: &'a str,
|
||||||
|
pub content: &'a str,
|
||||||
|
pub published_at: NaiveDate,
|
||||||
|
pub edited_at: Option<NaiveDate>,
|
||||||
|
pub active: bool,
|
||||||
|
}
|
32
backend/src/db/schema.rs
Normal file
32
backend/src/db/schema.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
diesel::table! {
|
||||||
|
configs {
|
||||||
|
id -> Integer,
|
||||||
|
active -> Bool,
|
||||||
|
name -> Text,
|
||||||
|
description -> Text,
|
||||||
|
copyright -> Text,
|
||||||
|
owner_name -> Text,
|
||||||
|
owner_email -> Text,
|
||||||
|
owner_website -> Nullable<Text>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
tags {
|
||||||
|
id -> Integer,
|
||||||
|
name -> Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
posts {
|
||||||
|
id -> Integer,
|
||||||
|
name -> Text,
|
||||||
|
slug -> Text,
|
||||||
|
description -> Text,
|
||||||
|
content -> Text,
|
||||||
|
published_at -> Date,
|
||||||
|
edited_at -> Nullable<Date>,
|
||||||
|
active -> Bool,
|
||||||
|
}
|
||||||
|
}
|
2
backend/src/lib.rs
Normal file
2
backend/src/lib.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod config;
|
||||||
|
pub mod db;
|
9
blog/blog.yml
Normal file
9
blog/blog.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
name: dergrimm's blog
|
||||||
|
description: |
|
||||||
|
Just some personal expericences about technology and programming.
|
||||||
|
Follow my RSS feed for more.
|
||||||
|
copyright: (C) 2022 - Dominic Grimm
|
||||||
|
owner:
|
||||||
|
name: Dominic Grimm
|
||||||
|
email: dominic@dergrimm.net
|
||||||
|
website: https://git.dergrimm.net/dergrimm
|
14
blog/posts/hello_world/post.md
Normal file
14
blog/posts/hello_world/post.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
name: Hello world!
|
||||||
|
slug: hello_world
|
||||||
|
description: Hello world to the internet. Set up my first blog!
|
||||||
|
published_at: 2023-02-06
|
||||||
|
edited_at: null
|
||||||
|
active: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hello world!
|
||||||
|
|
||||||
|
I just set up my first blog an am really proud of it!
|
||||||
|
|
||||||
|
So anyway, here I am.
|
37
docker-compose.yml
Normal file
37
docker-compose.yml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: docker.io/postgres:alpine
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- db:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
image: docker.io/adminer:standalone
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
backend:
|
||||||
|
image: git.dergrimm.net/dergrimm/blog_backend:latest
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
restart: always
|
||||||
|
command: worker
|
||||||
|
environment:
|
||||||
|
BACKEND_DB_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_USER}
|
||||||
|
volumes:
|
||||||
|
- ./blog:/blog
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db:
|
Loading…
Reference in a new issue