Isomorphic docker (#1124)

* Adding a way to GetComments for a community given its name only.

* Adding getcomments to api docs.

* A first pass at locally working isomorphic integration.

* Testing out cargo-husky.

* Testing a fail hook.

* Revert "Testing a fail hook."

This reverts commit 0941cf1736.

* Moving server to top level, now that UI is gone.

* Running cargo fmt using old way.

* Adding nginx, fixing up docker-compose files, fixing docs.

* Trying to re-add API tests.

* Fixing prod dockerfile.

* Redoing nightly fmt

* Trying to fix private message api test.

* Adding CommunityJoin, PostJoin instead of joins from GetComments, etc.

- Fixes #1122

* Fixing fmt.

* Fixing up docs.

* Removing translations.

* Adding apps / clients to readme.

* Fixing main image.

* Using new lemmy-isomorphic-ui with better javascript disabled.

* Try to fix image uploads in federation test

* Revert "Try to fix image uploads in federation test"

This reverts commit a2ddf2a90b.

* Fix post url federation

* Adding some more tests, some still broken.

* Don't need gitattributes anymore.

* Update local federation test setup

* Fixing tests.

* Fixing travis build.

* Fixing travis build, again.

* Changing lemmy-isomorphic-ui to lemmy-ui

* Error in travis build again.

Co-authored-by: Felix Ableitner <me@nutomic.com>
This commit is contained in:
Dessalines 2020-09-15 15:26:47 -04:00 committed by GitHub
parent b69524b498
commit 5c6258390c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
372 changed files with 4368 additions and 34786 deletions

2
.gitattributes vendored
View file

@ -1,2 +0,0 @@
* linguist-vendored
*.rs linguist-vendored=false

19
.gitignore vendored
View file

@ -6,16 +6,17 @@ ansible/passwords/
# docker build files # docker build files
docker/lemmy_mine.hjson docker/lemmy_mine.hjson
docker/dev/env_deploy.sh docker/dev/env_deploy.sh
docker/federation/volumes volumes
docker/federation-test/volumes
docker/dev/volumes
# local build files
build/
ui/src/translations
# ide config # ide config
.idea/ .idea
.vscode/ .vscode
# local build files
target target
env_setup.sh
query_testing/*.json
query_testing/*.json.old
# API tests
api_tests/node_modules

View file

@ -794,6 +794,12 @@ dependencies = [
"time 0.1.44", "time 0.1.44",
] ]
[[package]]
name = "cargo-husky"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.59" version = "1.0.59"
@ -1875,6 +1881,7 @@ dependencies = [
"base64 0.12.3", "base64 0.12.3",
"bcrypt", "bcrypt",
"captcha", "captcha",
"cargo-husky",
"chrono", "chrono",
"diesel", "diesel",
"diesel_migrations", "diesel_migrations",

View file

@ -59,3 +59,8 @@ anyhow = "1.0.32"
thiserror = "1.0.20" thiserror = "1.0.20"
background-jobs = " 0.8.0-alpha.2" background-jobs = " 0.8.0-alpha.2"
reqwest = { version = "0.10", features = ["json"] } reqwest = { version = "0.10", features = ["json"] }
[dev-dependencies.cargo-husky]
version = "1"
default-features = false # Disable features which are enabled by default
features = ["precommit-hook", "run-cargo-fmt", "run-cargo-clippy"]

View file

@ -11,7 +11,7 @@
<p align="center"> <p align="center">
<a href="https://dev.lemmy.ml/" rel="noopener"> <a href="https://dev.lemmy.ml/" rel="noopener">
<img width=200px height=200px src="ui/assets/favicon.svg"></a> <img width=200px height=200px src="https://raw.githubusercontent.com/LemmyNet/lemmy-ui/main/src/assets/icons/favicon.svg"></a>
<h3 align="center"><a href="https://dev.lemmy.ml">Lemmy</a></h3> <h3 align="center"><a href="https://dev.lemmy.ml">Lemmy</a></h3>
<p align="center"> <p align="center">
@ -108,12 +108,15 @@ Each Lemmy server can set its own moderation policy; appointing site-wide admins
### Apps ### Apps
- [lemmy-ui - The official web app for lemmy](https://github.com/LemmyNet/lemmy-ui)
- [Lemmur - A flutter lemmy app ( under development )](https://github.com/krawieck/lemmur)
- [Lemmy-mobile (Android / IOS) - React native ( under development )](https://github.com/koredefashokun/lemmy-mobile) - [Lemmy-mobile (Android / IOS) - React native ( under development )](https://github.com/koredefashokun/lemmy-mobile)
### Libraries ### Libraries
- [lemmy-js-client](https://github.com/LemmyNet/lemmy-js-client) - [lemmy-js-client](https://github.com/LemmyNet/lemmy-js-client)
- [Kotlin API ( under development )](https://github.com/eiknat/lemmy-client) - [Kotlin API ( under development )](https://github.com/eiknat/lemmy-client)
- [Dart API client ( under development )](https://github.com/krawieck/lemmy_api_client)
## Support / Donate ## Support / Donate

View file

@ -13,8 +13,6 @@
hostname: "{{ domain }}" hostname: "{{ domain }}"
# json web token for authorization between server and client # json web token for authorization between server and client
jwt_secret: "{{ jwt_password }}" jwt_secret: "{{ jwt_password }}"
# The location of the frontend
front_end_dir: "/app/dist"
# email sending configuration # email sending configuration
email: { email: {
# hostname of the smtp server # hostname of the smtp server

View file

@ -51,23 +51,41 @@ server {
# Upload limit for pictrs # Upload limit for pictrs
client_max_body_size 20M; client_max_body_size 20M;
# lemmy api
location /api/v1 {
proxy_pass http://0.0.0.0:8536/api/v1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Rate limit
limit_req zone=lemmy_ratelimit burst=30 nodelay;
}
# Docs
location /docs {
proxy_pass http://0.0.0.0:8536/docs;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# lemmy-ui
location / { location / {
proxy_pass http://0.0.0.0:8536; proxy_pass http://0.0.0.0:1235;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Rate limit
limit_req zone=lemmy_ratelimit burst=30 nodelay;
}
# Redirect pictshare images to pictrs # Redirect pictshare images to pictrs
location ~ /pictshare/(.*)$ { location ~ /pictshare/(.*)$ {

4
api_tests/jest.config.js Normal file
View file

@ -0,0 +1,4 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};

20
api_tests/package.json Normal file
View file

@ -0,0 +1,20 @@
{
"name": "api_tests",
"version": "0.0.1",
"description": "API tests for lemmy backend",
"main": "index.js",
"repository": "https://github.com/LemmyNet/lemmy",
"author": "Dessalines",
"license": "AGPL-3.0",
"scripts": {
"api-test": "jest src/ -i --verbose"
},
"devDependencies": {
"@types/jest": "^26.0.13",
"jest": "^26.4.2",
"lemmy-js-client": "^1.0.11",
"node-fetch": "^2.6.1",
"ts-jest": "^26.3.0",
"typescript": "^4.0.2"
}
}

View file

@ -235,7 +235,7 @@ test('Reply to a comment', async () => {
test('Mention beta', async () => { test('Mention beta', async () => {
// Create a mention on alpha // Create a mention on alpha
let mentionContent = 'A test mention of @lemmy_beta@lemmy-beta:8550'; let mentionContent = 'A test mention of @lemmy_beta@lemmy-beta:8551';
let commentRes = await createComment(alpha, postRes.post.id); let commentRes = await createComment(alpha, postRes.post.id);
await delay(); await delay();
let mentionRes = await createComment( let mentionRes = await createComment(
@ -275,7 +275,7 @@ test('A and G subscribe to B (center) A posts, G mentions B, it gets announced t
let gammaPost = search.posts[0]; let gammaPost = search.posts[0];
let commentContent = let commentContent =
'A jest test federated comment announce, lets mention @lemmy_beta@lemmy-beta:8550'; 'A jest test federated comment announce, lets mention @lemmy_beta@lemmy-beta:8551';
let commentRes = await createComment( let commentRes = await createComment(
gamma, gamma,
gammaPost.id, gammaPost.id,

View file

@ -1,8 +1,10 @@
jest.setTimeout(120000);
import { import {
alpha, alpha,
beta, beta,
setupLogins, setupLogins,
searchForBetaCommunity, searchForBetaCommunity,
searchForCommunity,
createCommunity, createCommunity,
deleteCommunity, deleteCommunity,
removeCommunity, removeCommunity,
@ -21,6 +23,17 @@ test('Create community', async () => {
let prevName = communityRes.community.name; let prevName = communityRes.community.name;
let communityRes2 = await createCommunity(alpha, prevName); let communityRes2 = await createCommunity(alpha, prevName);
expect(communityRes2['error']).toBe('community_already_exists'); expect(communityRes2['error']).toBe('community_already_exists');
await delay();
// Cache the community on beta, make sure it has the other fields
let searchShort = `!${prevName}@lemmy-alpha:8541`;
let search = await searchForCommunity(beta, searchShort);
let communityOnBeta = search.communities[0];
expect(communityOnBeta.name).toBe(communityRes.community.name);
expect(communityOnBeta.title).toBe(communityRes.community.title);
expect(communityOnBeta.description).toBe(communityRes.community.description);
expect(communityOnBeta.icon).toBe(communityRes.community.icon);
expect(communityOnBeta.banner).toBe(communityRes.community.banner);
}); });
test('Delete community', async () => { test('Delete community', async () => {

View file

@ -1,3 +1,4 @@
jest.setTimeout(120000);
import { import {
alpha, alpha,
setupLogins, setupLogins,

View file

@ -56,6 +56,10 @@ test('Create a post', async () => {
expect(betaPost.community_local).toBe(true); expect(betaPost.community_local).toBe(true);
expect(betaPost.creator_local).toBe(false); expect(betaPost.creator_local).toBe(false);
expect(betaPost.score).toBe(1); expect(betaPost.score).toBe(1);
expect(betaPost.name).toBe(postRes.post.name);
expect(betaPost.body).toBe(postRes.post.body);
expect(betaPost.url).toBe(postRes.post.url);
expect(betaPost.nsfw).toBe(postRes.post.nsfw);
// Delta only follows beta, so it should not see an alpha ap_id // Delta only follows beta, so it should not see an alpha ap_id
let searchDelta = await searchPost(delta, postRes.post); let searchDelta = await searchPost(delta, postRes.post);

View file

@ -1,3 +1,4 @@
jest.setTimeout(120000);
import { import {
alpha, alpha,
beta, beta,

View file

@ -50,23 +50,23 @@ export interface API {
} }
export let alpha: API = { export let alpha: API = {
client: new LemmyHttp('http://localhost:8540/api/v1'), client: new LemmyHttp('http://localhost:8541/api/v1'),
}; };
export let beta: API = { export let beta: API = {
client: new LemmyHttp('http://localhost:8550/api/v1'), client: new LemmyHttp('http://localhost:8551/api/v1'),
}; };
export let gamma: API = { export let gamma: API = {
client: new LemmyHttp('http://localhost:8560/api/v1'), client: new LemmyHttp('http://localhost:8561/api/v1'),
}; };
export let delta: API = { export let delta: API = {
client: new LemmyHttp('http://localhost:8570/api/v1'), client: new LemmyHttp('http://localhost:8571/api/v1'),
}; };
export let epsilon: API = { export let epsilon: API = {
client: new LemmyHttp('http://localhost:8580/api/v1'), client: new LemmyHttp('http://localhost:8581/api/v1'),
}; };
export async function setupLogins() { export async function setupLogins() {
@ -120,8 +120,12 @@ export async function createPost(
community_id: number community_id: number
): Promise<PostResponse> { ): Promise<PostResponse> {
let name = 'A jest test post'; let name = 'A jest test post';
let body = 'Some body';
let url = 'https://google.com/';
let form: PostForm = { let form: PostForm = {
name, name,
url,
body,
auth: api.auth, auth: api.auth,
community_id, community_id,
nsfw: false, nsfw: false,
@ -232,7 +236,20 @@ export async function searchForBetaCommunity(
// Make sure lemmy-beta/c/main is cached on lemmy_alpha // Make sure lemmy-beta/c/main is cached on lemmy_alpha
// Use short-hand search url // Use short-hand search url
let form: SearchForm = { let form: SearchForm = {
q: '!main@lemmy-beta:8550', q: '!main@lemmy-beta:8551',
type_: SearchType.Communities,
sort: SortType.TopAll,
};
return api.client.search(form);
}
export async function searchForCommunity(
api: API,
q: string,
): Promise<SearchResponse> {
// Use short-hand search url
let form: SearchForm = {
q,
type_: SearchType.Communities, type_: SearchType.Communities,
sort: SortType.TopAll, sort: SortType.TopAll,
}; };
@ -369,9 +386,15 @@ export async function createCommunity(
api: API, api: API,
name_: string = randomString(5) name_: string = randomString(5)
): Promise<CommunityResponse> { ): Promise<CommunityResponse> {
let description = 'a sample description';
let icon = 'https://image.flaticon.com/icons/png/512/35/35896.png';
let banner = 'https://image.flaticon.com/icons/png/512/35/35896.png';
let form: CommunityForm = { let form: CommunityForm = {
name: name_, name: name_,
title: name_, title: name_,
description,
icon,
banner,
category_id: 1, category_id: 1,
nsfw: false, nsfw: false,
auth: api.auth, auth: api.auth,

View file

@ -1,3 +1,4 @@
jest.setTimeout(120000);
import { import {
alpha, alpha,
beta, beta,
@ -17,7 +18,7 @@ test('Create user', async () => {
let site = await getSite(alpha, auth); let site = await getSite(alpha, auth);
expect(site.my_user).toBeDefined(); expect(site.my_user).toBeDefined();
apShortname = `@${site.my_user.name}@lemmy-alpha:8540`; apShortname = `@${site.my_user.name}@lemmy-alpha:8541`;
}); });
test('Save user settings, check changed bio from beta', async () => { test('Save user settings, check changed bio from beta', async () => {

3659
api_tests/yarn.lock Normal file

File diff suppressed because it is too large Load diff

View file

@ -33,8 +33,6 @@
port: 8536 port: 8536
# json web token for authorization between server and client # json web token for authorization between server and client
jwt_secret: "changeme" jwt_secret: "changeme"
# The location of the frontend
front_end_dir: "../ui/dist"
# address where pictrs is available # address where pictrs is available
pictrs_url: "http://pictrs:8080" pictrs_url: "http://pictrs:8080"
# rate limits for various user actions, by user ip # rate limits for various user actions, by user ip

View file

@ -1,15 +1,3 @@
FROM node:10-jessie as node
WORKDIR /app/ui
# Cache deps
COPY ui/package.json ui/yarn.lock ./
RUN yarn install --pure-lockfile
# Build
COPY ui /app/ui
RUN yarn build
FROM ekidd/rust-musl-builder:nightly-2020-05-07 as rust FROM ekidd/rust-musl-builder:nightly-2020-05-07 as rust
# Cache deps # Cache deps
@ -27,22 +15,22 @@ RUN mkdir -p lemmy_db/src/ \
lemmy lemmy
# Copy the cargo tomls # Copy the cargo tomls
COPY server/Cargo.toml server/Cargo.lock ./ COPY Cargo.toml Cargo.lock ./
COPY server/lemmy_db/Cargo.toml ./lemmy_db/ COPY lemmy_db/Cargo.toml ./lemmy_db/
COPY server/lemmy_utils/Cargo.toml ./lemmy_utils/ COPY lemmy_utils/Cargo.toml ./lemmy_utils/
COPY server/lemmy_api_structs/Cargo.toml ./lemmy_api_structs/ COPY lemmy_api_structs/Cargo.toml ./lemmy_api_structs/
COPY server/lemmy_rate_limit/Cargo.toml ./lemmy_rate_limit/ COPY lemmy_rate_limit/Cargo.toml ./lemmy_rate_limit/
# Cache the deps # Cache the deps
RUN cargo build-deps RUN cargo build-deps
# Copy the src folders # Copy the src folders
COPY server/src ./src/ COPY src ./src/
COPY server/lemmy_db/src ./lemmy_db/src/ COPY lemmy_db/src ./lemmy_db/src/
COPY server/lemmy_utils/src/ ./lemmy_utils/src/ COPY lemmy_utils/src/ ./lemmy_utils/src/
COPY server/lemmy_api_structs/src/ ./lemmy_api_structs/src/ COPY lemmy_api_structs/src/ ./lemmy_api_structs/src/
COPY server/lemmy_rate_limit/src/ ./lemmy_rate_limit/src/ COPY lemmy_rate_limit/src/ ./lemmy_rate_limit/src/
COPY server/migrations ./migrations/ COPY migrations ./migrations/
# Build for debug # Build for debug
RUN cargo build RUN cargo build
@ -62,10 +50,9 @@ RUN apk add libpq
RUN apk add espeak RUN apk add espeak
# Copy resources # Copy resources
COPY server/config/defaults.hjson /config/defaults.hjson COPY config/defaults.hjson /config/defaults.hjson
COPY --from=rust /app/server/target/x86_64-unknown-linux-musl/debug/lemmy_server /app/lemmy COPY --from=rust /app/server/target/x86_64-unknown-linux-musl/debug/lemmy_server /app/lemmy
COPY --from=docs /app/docs/book/ /app/dist/documentation/ COPY --from=docs /app/docs/book/ /app/documentation/
COPY --from=node /app/ui/dist /app/dist
RUN addgroup -g 1000 lemmy RUN addgroup -g 1000 lemmy
RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy

View file

@ -15,6 +15,16 @@ services:
- pictrs - pictrs
- postgres - postgres
- iframely - iframely
lemmy-ui:
image: dessalines/lemmy-ui:v0.0.14
ports:
- "1235:1234"
environment:
- LEMMY_INTERNAL_HOST=lemmy:8536
- LEMMY_EXTERNAL_HOST=localhost:8536
- LEMMY_HTTPS=false
depends_on:
- lemmy
postgres: postgres:
image: postgres:12-alpine image: postgres:12-alpine

View file

@ -28,17 +28,24 @@ services:
volumes: volumes:
- ./volumes/pictrs_alpha:/mnt - ./volumes/pictrs_alpha:/mnt
lemmy-alpha-ui:
image: dessalines/lemmy-ui:v0.0.14
environment:
- LEMMY_INTERNAL_HOST=lemmy-alpha:8541
- LEMMY_EXTERNAL_HOST=localhost:8541
- LEMMY_HTTPS=false
depends_on:
- lemmy-alpha
lemmy-alpha: lemmy-alpha:
image: lemmy-federation:latest image: lemmy-federation:latest
environment: environment:
- LEMMY_HOSTNAME=lemmy-alpha:8540 - LEMMY_HOSTNAME=lemmy-alpha:8541
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_alpha:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_alpha:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8540 - LEMMY_PORT=8541
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha - LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-alpha - LEMMY_SETUP__SITE_NAME=lemmy-alpha
@ -49,6 +56,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_alpha - postgres_alpha
ports:
- "8541:8541"
postgres_alpha: postgres_alpha:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -58,17 +67,24 @@ services:
volumes: volumes:
- ./volumes/postgres_alpha:/var/lib/postgresql/data - ./volumes/postgres_alpha:/var/lib/postgresql/data
lemmy-beta-ui:
image: dessalines/lemmy-ui:v0.0.14
environment:
- LEMMY_INTERNAL_HOST=lemmy-beta:8551
- LEMMY_EXTERNAL_HOST=localhost:8551
- LEMMY_HTTPS=false
depends_on:
- lemmy-beta
lemmy-beta: lemmy-beta:
image: lemmy-federation:latest image: lemmy-federation:latest
environment: environment:
- LEMMY_HOSTNAME=lemmy-beta:8550 - LEMMY_HOSTNAME=lemmy-beta:8551
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_beta:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_beta:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8550 - LEMMY_PORT=8551
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta - LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-beta - LEMMY_SETUP__SITE_NAME=lemmy-beta
@ -79,6 +95,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_beta - postgres_beta
ports:
- "8551:8551"
postgres_beta: postgres_beta:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -88,17 +106,24 @@ services:
volumes: volumes:
- ./volumes/postgres_beta:/var/lib/postgresql/data - ./volumes/postgres_beta:/var/lib/postgresql/data
lemmy-gamma-ui:
image: dessalines/lemmy-ui:v0.0.14
environment:
- LEMMY_INTERNAL_HOST=lemmy-gamma:8561
- LEMMY_EXTERNAL_HOST=localhost:8561
- LEMMY_HTTPS=false
depends_on:
- lemmy-gamma
lemmy-gamma: lemmy-gamma:
image: lemmy-federation:latest image: lemmy-federation:latest
environment: environment:
- LEMMY_HOSTNAME=lemmy-gamma:8560 - LEMMY_HOSTNAME=lemmy-gamma:8561
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_gamma:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_gamma:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8560 - LEMMY_PORT=8561
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma - LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-gamma - LEMMY_SETUP__SITE_NAME=lemmy-gamma
@ -109,6 +134,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_gamma - postgres_gamma
ports:
- "8561:8561"
postgres_gamma: postgres_gamma:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -119,17 +146,24 @@ services:
- ./volumes/postgres_gamma:/var/lib/postgresql/data - ./volumes/postgres_gamma:/var/lib/postgresql/data
# An instance with only an allowlist for beta # An instance with only an allowlist for beta
lemmy-delta-ui:
image: dessalines/lemmy-ui:v0.0.14
environment:
- LEMMY_INTERNAL_HOST=lemmy-delta:8571
- LEMMY_EXTERNAL_HOST=localhost:8571
- LEMMY_HTTPS=false
depends_on:
- lemmy-delta
lemmy-delta: lemmy-delta:
image: lemmy-federation:latest image: lemmy-federation:latest
environment: environment:
- LEMMY_HOSTNAME=lemmy-delta:8570 - LEMMY_HOSTNAME=lemmy-delta:8571
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta
- LEMMY_PORT=8570 - LEMMY_PORT=8571
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta - LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-delta - LEMMY_SETUP__SITE_NAME=lemmy-delta
@ -140,6 +174,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_delta - postgres_delta
ports:
- "8571:8571"
postgres_delta: postgres_delta:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -150,17 +186,24 @@ services:
- ./volumes/postgres_delta:/var/lib/postgresql/data - ./volumes/postgres_delta:/var/lib/postgresql/data
# An instance who has a blocklist, with lemmy-alpha blocked # An instance who has a blocklist, with lemmy-alpha blocked
lemmy-epsilon-ui:
image: dessalines/lemmy-ui:v0.0.14
environment:
- LEMMY_INTERNAL_HOST=lemmy-epsilon:8581
- LEMMY_EXTERNAL_HOST=localhost:8581
- LEMMY_HTTPS=false
depends_on:
- lemmy-epsilon
lemmy-epsilon: lemmy-epsilon:
image: lemmy-federation:latest image: lemmy-federation:latest
environment: environment:
- LEMMY_HOSTNAME=lemmy-epsilon:8580 - LEMMY_HOSTNAME=lemmy-epsilon:8581
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha - LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha
- LEMMY_PORT=8580 - LEMMY_PORT=8581
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon - LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-epsilon - LEMMY_SETUP__SITE_NAME=lemmy-epsilon
@ -171,6 +214,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_epsilon - postgres_epsilon
ports:
- "8581:8581"
postgres_epsilon: postgres_epsilon:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:

View file

@ -11,21 +11,21 @@ http {
# Upload limit for pictshare # Upload limit for pictshare
client_max_body_size 50M; client_max_body_size 50M;
location /api/v1 {
proxy_pass http://lemmy-alpha:8541/api/v1;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / { location / {
proxy_pass http://lemmy-alpha:8540; proxy_pass http://lemmy-alpha-ui:1234;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid # Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent; rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} }
location /iframely/ { location /iframely/ {
proxy_pass http://iframely:80/; proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@ -42,21 +42,21 @@ http {
# Upload limit for pictshare # Upload limit for pictshare
client_max_body_size 50M; client_max_body_size 50M;
location /api/v1 {
proxy_pass http://lemmy-beta:8551/api/v1;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / { location / {
proxy_pass http://lemmy-beta:8550; proxy_pass http://lemmy-beta-ui:1234;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid # Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent; rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} }
location /iframely/ { location /iframely/ {
proxy_pass http://iframely:80/; proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@ -73,21 +73,21 @@ http {
# Upload limit for pictshare # Upload limit for pictshare
client_max_body_size 50M; client_max_body_size 50M;
location /api/v1 {
proxy_pass http://lemmy-gamma:8561/api/v1;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / { location / {
proxy_pass http://lemmy-gamma:8560; proxy_pass http://lemmy-gamma-ui:1234;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid # Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent; rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} }
location /iframely/ { location /iframely/ {
proxy_pass http://iframely:80/; proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@ -104,21 +104,21 @@ http {
# Upload limit for pictshare # Upload limit for pictshare
client_max_body_size 50M; client_max_body_size 50M;
location /api/v1 {
proxy_pass http://lemmy-delta:8571/api/v1;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / { location / {
proxy_pass http://lemmy-delta:8570; proxy_pass http://lemmy-delta-ui:1234;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid # Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent; rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} }
location /iframely/ { location /iframely/ {
proxy_pass http://iframely:80/; proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@ -135,21 +135,21 @@ http {
# Upload limit for pictshare # Upload limit for pictshare
client_max_body_size 50M; client_max_body_size 50M;
location /api/v1 {
proxy_pass http://lemmy-epsilon:8581/api/v1;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / { location / {
proxy_pass http://lemmy-epsilon:8580; proxy_pass http://lemmy-epsilon-ui:1234;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid # Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent; rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} }
location /iframely/ { location /iframely/ {
proxy_pass http://iframely:80/; proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;

View file

@ -15,13 +15,14 @@ sudo chown -R 991:991 volumes/pictrs_alpha
sudo docker-compose up -d sudo docker-compose up -d
pushd ../../ui pushd ../../api_tests
echo "Waiting for Lemmy to start..." echo "Waiting for Lemmy to start..."
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8541/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8551/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8561/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8570/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8571/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8580/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8581/api/v1/site')" != "200" ]]; do sleep 1; done
yarn
yarn api-test || true yarn api-test || true
popd popd

View file

@ -30,8 +30,6 @@
# host where postgres is running # host where postgres is running
host: "postgres" host: "postgres"
} }
# The location of the frontend
front_end_dir: "/app/dist"
# # optional: email sending configuration # # optional: email sending configuration
# email: { # email: {
# # hostname of the smtp server # # hostname of the smtp server

View file

@ -10,17 +10,17 @@ WORKDIR /app
RUN sudo chown -R rust:rust . RUN sudo chown -R rust:rust .
RUN USER=root cargo new server RUN USER=root cargo new server
WORKDIR /app/server WORKDIR /app/server
COPY server/Cargo.toml server/Cargo.lock ./ COPY Cargo.toml Cargo.lock ./
COPY server/lemmy_db ./lemmy_db COPY lemmy_db ./lemmy_db
COPY server/lemmy_utils ./lemmy_utils COPY lemmy_utils ./lemmy_utils
COPY server/lemmy_api_structs ./lemmy_api_structs COPY lemmy_api_structs ./lemmy_api_structs
COPY server/lemmy_rate_limit ./lemmy_rate_limit COPY lemmy_rate_limit ./lemmy_rate_limit
RUN mkdir -p ./src/bin \ RUN mkdir -p ./src/bin \
&& echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs && echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs
RUN cargo build --release RUN cargo build --release
RUN find target/$CARGO_BUILD_TARGET/$RUSTRELEASEDIR -type f -name "$(echo "lemmy_server" | tr '-' '_')*" -exec touch -t 200001010000 {} + RUN find target/$CARGO_BUILD_TARGET/$RUSTRELEASEDIR -type f -name "$(echo "lemmy_server" | tr '-' '_')*" -exec touch -t 200001010000 {} +
COPY server/src ./src/ COPY src ./src/
COPY server/migrations ./migrations/ COPY migrations ./migrations/
# build for release # build for release
# workaround for https://github.com/rust-lang/rust/issues/62896 # workaround for https://github.com/rust-lang/rust/issues/62896
@ -36,18 +36,6 @@ WORKDIR /app
COPY --chown=rust:rust docs ./docs COPY --chown=rust:rust docs ./docs
RUN mdbook build docs/ RUN mdbook build docs/
FROM node:12-buster as node
WORKDIR /app/ui
# Cache deps
COPY ui/package.json ui/yarn.lock ./
RUN yarn install --pure-lockfile --network-timeout 600000
# Build
COPY ui /app/ui
RUN yarn build
FROM alpine:3.12 as lemmy FROM alpine:3.12 as lemmy
# Install libpq for postgres # Install libpq for postgres
@ -60,10 +48,9 @@ RUN addgroup -g 1000 lemmy
RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
# Copy resources # Copy resources
COPY --chown=lemmy:lemmy server/config/defaults.hjson /config/defaults.hjson COPY --chown=lemmy:lemmy config/defaults.hjson /config/defaults.hjson
COPY --chown=lemmy:lemmy --from=rust /app/server/lemmy_server /app/lemmy COPY --chown=lemmy:lemmy --from=rust /app/server/lemmy_server /app/lemmy
COPY --chown=lemmy:lemmy --from=docs /app/docs/book/ /app/dist/documentation/ COPY --chown=lemmy:lemmy --from=docs /app/docs/book/ /app/documentation/
COPY --chown=lemmy:lemmy --from=node /app/ui/dist /app/dist
RUN chown lemmy:lemmy /app/lemmy RUN chown lemmy:lemmy /app/lemmy
USER lemmy USER lemmy

View file

@ -13,8 +13,8 @@ third_semver=$(echo $new_tag | cut -d "." -f 3)
# Setting the version on the front end # Setting the version on the front end
cd ../../ cd ../../
# Setting the version on the backend # Setting the version on the backend
echo "pub const VERSION: &str = \"$new_tag\";" > "server/src/version.rs" echo "pub const VERSION: &str = \"$new_tag\";" > "src/version.rs"
git add "server/src/version.rs" git add "src/version.rs"
# Setting the version for Ansible # Setting the version for Ansible
echo $new_tag > "ansible/VERSION" echo $new_tag > "ansible/VERSION"
git add "ansible/VERSION" git add "ansible/VERSION"

View file

@ -25,6 +25,17 @@ services:
- pictrs - pictrs
- iframely - iframely
lemmy-ui:
image: dessalines/lemmy-ui:v0.0.14
ports:
- "1235:1234"
environment:
- LEMMY_INTERNAL_HOST=lemmy:8536
- LEMMY_EXTERNAL_HOST=localhost:8536
- LEMMY_HTTPS=false
depends_on:
- lemmy
pictrs: pictrs:
image: asonix/pictrs:v0.1.13-r0 image: asonix/pictrs:v0.1.13-r0
ports: ports:

View file

@ -1,45 +1,16 @@
version: '3.3' version: '3.3'
services: services:
nginx:
image: nginx:1.17-alpine
ports:
- "8540:8540"
- "8550:8550"
- "8560:8560"
- "8570:8570"
- "8580:8580"
volumes:
# Hack to make this work from both docker/federation/ and docker/federation-test/
- ../federation/nginx.conf:/etc/nginx/nginx.conf
restart: on-failure
depends_on:
- pictrs
- iframely
- lemmy-alpha
- lemmy-beta
- lemmy-gamma
- lemmy-delta
- lemmy-epsilon
pictrs:
restart: always
image: asonix/pictrs:v0.1.13-r0
user: 991:991
volumes:
- ./volumes/pictrs_alpha:/mnt
lemmy-alpha: lemmy-alpha:
image: dessalines/lemmy:travis image: dessalines/lemmy:travis
environment: environment:
- LEMMY_HOSTNAME=lemmy-alpha:8540 - LEMMY_HOSTNAME=lemmy-alpha:8541
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_alpha:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_alpha:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8540 - LEMMY_PORT=8541
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha - LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-alpha - LEMMY_SETUP__SITE_NAME=lemmy-alpha
@ -50,6 +21,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_alpha - postgres_alpha
ports:
- "8541:8541"
postgres_alpha: postgres_alpha:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -62,14 +35,13 @@ services:
lemmy-beta: lemmy-beta:
image: dessalines/lemmy:travis image: dessalines/lemmy:travis
environment: environment:
- LEMMY_HOSTNAME=lemmy-beta:8550 - LEMMY_HOSTNAME=lemmy-beta:8551
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_beta:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_beta:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8550 - LEMMY_PORT=8551
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta - LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-beta - LEMMY_SETUP__SITE_NAME=lemmy-beta
@ -80,6 +52,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_beta - postgres_beta
ports:
- "8551:8551"
postgres_beta: postgres_beta:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -92,14 +66,13 @@ services:
lemmy-gamma: lemmy-gamma:
image: dessalines/lemmy:travis image: dessalines/lemmy:travis
environment: environment:
- LEMMY_HOSTNAME=lemmy-gamma:8560 - LEMMY_HOSTNAME=lemmy-gamma:8561
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_gamma:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_gamma:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8560 - LEMMY_PORT=8561
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma - LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-gamma - LEMMY_SETUP__SITE_NAME=lemmy-gamma
@ -110,6 +83,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_gamma - postgres_gamma
ports:
- "8561:8561"
postgres_gamma: postgres_gamma:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -123,14 +98,13 @@ services:
lemmy-delta: lemmy-delta:
image: dessalines/lemmy:travis image: dessalines/lemmy:travis
environment: environment:
- LEMMY_HOSTNAME=lemmy-delta:8570 - LEMMY_HOSTNAME=lemmy-delta:8571
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta
- LEMMY_PORT=8570 - LEMMY_PORT=8571
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta - LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-delta - LEMMY_SETUP__SITE_NAME=lemmy-delta
@ -141,6 +115,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_delta - postgres_delta
ports:
- "8571:8571"
postgres_delta: postgres_delta:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -154,14 +130,13 @@ services:
lemmy-epsilon: lemmy-epsilon:
image: dessalines/lemmy:travis image: dessalines/lemmy:travis
environment: environment:
- LEMMY_HOSTNAME=lemmy-epsilon:8580 - LEMMY_HOSTNAME=lemmy-epsilon:8581
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy
- LEMMY_JWT_SECRET=changeme - LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha - LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha
- LEMMY_PORT=8580 - LEMMY_PORT=8581
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon - LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-epsilon - LEMMY_SETUP__SITE_NAME=lemmy-epsilon
@ -172,6 +147,8 @@ services:
- RUST_LOG=debug - RUST_LOG=debug
depends_on: depends_on:
- postgres_epsilon - postgres_epsilon
ports:
- "8581:8581"
postgres_epsilon: postgres_epsilon:
image: postgres:12-alpine image: postgres:12-alpine
environment: environment:
@ -180,9 +157,3 @@ services:
- POSTGRES_DB=lemmy - POSTGRES_DB=lemmy
volumes: volumes:
- ./volumes/postgres_epsilon:/var/lib/postgresql/data - ./volumes/postgres_epsilon:/var/lib/postgresql/data
iframely:
image: dogbin/iframely:latest
volumes:
- ../iframely.config.local.js:/iframely/config.local.js:ro
restart: always

View file

@ -12,13 +12,13 @@ sudo docker build ../../ --file ../prod/Dockerfile --tag dessalines/lemmy:travis
sudo docker-compose up -d sudo docker-compose up -d
pushd ../../ui pushd ../../api_tests
echo "Waiting for Lemmy to start..." echo "Waiting for Lemmy to start..."
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8541/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8551/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8561/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8570/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8571/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8580/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8581/api/v1/site')" != "200" ]]; do sleep 1; done
yarn yarn
yarn api-test yarn api-test
popd popd

View file

@ -31,4 +31,5 @@
- High performance. - High performance.
- Server is written in rust. - Server is written in rust.
- Front end is `~80kB` gzipped. - Front end is `~80kB` gzipped.
- Front end works without javascript (read-only).
- Supports arm64 / Raspberry Pi. - Supports arm64 / Raspberry Pi.

View file

@ -1,7 +1,7 @@
# Configuration # Configuration
The configuration is based on the file The configuration is based on the file
[defaults.hjson](https://yerbamate.dev/LemmyNet/lemmy/src/branch/main/server/config/defaults.hjson). [defaults.hjson](https://yerbamate.dev/LemmyNet/lemmy/src/branch/main/config/defaults.hjson).
This file also contains documentation for all the available options. To override the defaults, you This file also contains documentation for all the available options. To override the defaults, you
can copy the options you want to change into your local `config.hjson` file. can copy the options you want to change into your local `config.hjson` file.

View file

@ -18,13 +18,14 @@ Check out [Lemmy's Weblate](https://weblate.yerbamate.dev/projects/lemmy/) for t
### Front end ### Front end
- The front end is written in `typescript`, using a react-like framework called [inferno](https://infernojs.org/). All UI elements are reusable `.tsx` components. - The front end is written in `typescript`, using a react-like framework called [inferno](https://infernojs.org/). All UI elements are reusable `.tsx` components.
- The main page and routing are in `ui/src/index.tsx`. - The front end repository is [lemmy-ui](https://github.com/LemmyNet/lemmy-ui).
- The components are located in `ui/src/components`. - The routes are at `src/shared/routes.ts`.
- The components are located in `src/shared/components`.
### Back end ### Back end
- The back end is written in `rust`, using `diesel`, and `actix`. - The back end is written in `rust`, using `diesel`, and `actix`.
- The server source code is split into main sections in `server/src`. These include: - The server source code is split into main sections in `src`. These include:
- `db` - The low level database actions. - `db` - The low level database actions.
- Database additions are done using diesel migrations. Run `diesel migration generate xxxxx` to add new things. - Database additions are done using diesel migrations. Run `diesel migration generate xxxxx` to add new things.
- `api` - The high level user interactions (things like `CreateComment`) - `api` - The high level user interactions (things like `CreateComment`)

View file

@ -9,7 +9,9 @@ cd lemmy/docker/dev
sudo docker-compose up --no-deps --build sudo docker-compose up --no-deps --build
``` ```
and go to http://localhost:8536. and go to http://localhost:1235.
*Note: many features (like docs and pictures) will not work without using an nginx profile like that in `ansible/templates/nginx.conf`.
To speed up the Docker compile, add the following to `/etc/docker/daemon.json` and restart Docker. To speed up the Docker compile, add the following to `/etc/docker/daemon.json` and restart Docker.
``` ```

View file

@ -20,28 +20,22 @@ Finally, install Node and Yarn.
brew install node yarn brew install node yarn
``` ```
### Get the source code ### Get the back end source code
``` ```
git clone https://github.com/LemmyNet/lemmy.git git clone https://github.com/LemmyNet/lemmy.git
# or alternatively from gitea # or alternatively from gitea
# git clone https://yerbamate.dev/LemmyNet/lemmy.git # git clone https://yerbamate.dev/LemmyNet/lemmy.git
``` ```
All the following commands need to be run either in `lemmy/server` or `lemmy/ui`, as indicated
by the `cd` command.
### Build the backend (Rust) ### Build the backend (Rust)
``` ```
cd server
cargo build cargo build
# for development, use `cargo check` instead) # for development, use `cargo check` instead)
``` ```
### Build the frontend (Typescript) ### Get the front end source code
``` ```
cd ui git clone https://github.com/LemmyNet/lemmy-ui.git
yarn
yarn build
``` ```
### Setup postgresql ### Setup postgresql
@ -50,7 +44,7 @@ yarn build
sudo apt install postgresql sudo apt install postgresql
sudo systemctl start postgresql sudo systemctl start postgresql
# Either execute server/db-init.sh, or manually initialize the postgres database: # Either execute db-init.sh, or manually initialize the postgres database:
sudo -u postgres psql -c "create user lemmy with password 'password' superuser;" -U postgres sudo -u postgres psql -c "create user lemmy with password 'password' superuser;" -U postgres
sudo -u postgres psql -c 'create database lemmy with owner lemmy;' -U postgres sudo -u postgres psql -c 'create database lemmy with owner lemmy;' -U postgres
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
@ -62,7 +56,7 @@ brew install postgresql
brew services start postgresql brew services start postgresql
/usr/local/opt/postgres/bin/createuser -s postgres /usr/local/opt/postgres/bin/createuser -s postgres
# Either execute server/db-init.sh, or manually initialize the postgres database: # Either execute db-init.sh, or manually initialize the postgres database:
psql -c "create user lemmy with password 'password' superuser;" -U postgres psql -c "create user lemmy with password 'password' superuser;" -U postgres
psql -c 'create database lemmy with owner lemmy;' -U postgres psql -c 'create database lemmy with owner lemmy;' -U postgres
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
@ -70,21 +64,22 @@ export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
### Run a local development instance ### Run a local development instance
``` ```
# run each of these in a seperate terminal cd lemmy
cd server && cargo run cargo run
cd ui && yarn start
``` ```
Then open [localhost:4444](http://localhost:4444) in your browser. It will auto-refresh if you edit Then open [localhost:1235](http://localhost:1235) in your browser. To reload back-end changes, you will have to rerun `cargo run`. You can use `cargo check` as a faster way to find compilation errors.
any frontend files. For backend coding, you will have to rerun `cargo run`. You can use
`cargo check` as a faster way to find compilation errors. To do front end development:
To speed up incremental builds, you can add the following to `~/.cargo/config`:
``` ```
[target.x86_64-unknown-linux-gnu] cd lemmy-ui
rustflags = ["-Clink-arg=-fuse-ld=lld"] yarn
yarn dev
``` ```
and goto [localhost:1234](http://localhost:1234). Front end saves should rebuild the project.
Note that this setup doesn't include image uploads or link previews (provided by pict-rs and Note that this setup doesn't include image uploads or link previews (provided by pict-rs and
iframely respectively). If you want to test those, you should use the iframely respectively). If you want to test those, you should use the
[Docker development](contributing_docker_development.md). [Docker development](contributing_docker_development.md).

View file

@ -3,7 +3,7 @@
#### Rust #### Rust
After installing [local development dependencies](contributing_local_development.md), run the After installing [local development dependencies](contributing_local_development.md), run the
following commands in the `server` subfolder: following commands:
```bash ```bash
psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;" psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"

View file

@ -12,7 +12,8 @@ Lemmy uses [Bootstrap v4](https://getbootstrap.com/), and very few custom css cl
## Adding ## Adding
1. Copy `{my-theme-name}.min.css` to `ui/assets/css/themes`. (You can also copy the `_variables.scss` here if you want). 1. Fork the [lemmy-ui](https://github.com/LemmyNet/lemmy-ui).
1. Go to `ui/src/utils.ts` and add `{my-theme-name}` to the themes list. 1. Copy `{my-theme-name}.min.css` to `src/assets/css/themes`. (You can also copy the `_variables.scss` here if you want).
1. Go to `src/shared/utils.ts` and add `{my-theme-name}` to the themes list.
1. Test locally 1. Test locally
1. Do a pull request with those changes. 1. Do a pull request with those changes.

View file

@ -1,6 +1,6 @@
# Lemmy API # Lemmy API
*Note: this may lag behind the actual API endpoints [here](../server/src/api). The API should be considered unstable and may change any time.* *Note: this may lag behind the actual API endpoints [here](../src/api). The API should be considered unstable and may change any time.*
<!-- toc --> <!-- toc -->
@ -28,214 +28,234 @@
- [Request](#request-1) - [Request](#request-1)
- [Response](#response-1) - [Response](#response-1)
- [HTTP](#http-2) - [HTTP](#http-2)
+ [Get User Details](#get-user-details) + [Get Captcha](#get-captcha)
- [Request](#request-2) - [Request](#request-2)
- [Response](#response-2) - [Response](#response-2)
- [HTTP](#http-3) - [HTTP](#http-3)
+ [Save User Settings](#save-user-settings) + [Get User Details](#get-user-details)
- [Request](#request-3) - [Request](#request-3)
- [Response](#response-3) - [Response](#response-3)
- [HTTP](#http-4) - [HTTP](#http-4)
+ [Get Replies / Inbox](#get-replies--inbox) + [Save User Settings](#save-user-settings)
- [Request](#request-4) - [Request](#request-4)
- [Response](#response-4) - [Response](#response-4)
- [HTTP](#http-5) - [HTTP](#http-5)
+ [Get User Mentions](#get-user-mentions) + [Get Replies / Inbox](#get-replies--inbox)
- [Request](#request-5) - [Request](#request-5)
- [Response](#response-5) - [Response](#response-5)
- [HTTP](#http-6) - [HTTP](#http-6)
+ [Mark User Mention as read](#mark-user-mention-as-read) + [Get User Mentions](#get-user-mentions)
- [Request](#request-6) - [Request](#request-6)
- [Response](#response-6) - [Response](#response-6)
- [HTTP](#http-7) - [HTTP](#http-7)
+ [Get Private Messages](#get-private-messages) + [Mark User Mention as read](#mark-user-mention-as-read)
- [Request](#request-7) - [Request](#request-7)
- [Response](#response-7) - [Response](#response-7)
- [HTTP](#http-8) - [HTTP](#http-8)
+ [Create Private Message](#create-private-message) + [Get Private Messages](#get-private-messages)
- [Request](#request-8) - [Request](#request-8)
- [Response](#response-8) - [Response](#response-8)
- [HTTP](#http-9) - [HTTP](#http-9)
+ [Edit Private Message](#edit-private-message) + [Create Private Message](#create-private-message)
- [Request](#request-9) - [Request](#request-9)
- [Response](#response-9) - [Response](#response-9)
- [HTTP](#http-10) - [HTTP](#http-10)
+ [Delete Private Message](#delete-private-message) + [Edit Private Message](#edit-private-message)
- [Request](#request-10) - [Request](#request-10)
- [Response](#response-10) - [Response](#response-10)
- [HTTP](#http-11) - [HTTP](#http-11)
+ [Mark Private Message as Read](#mark-private-message-as-read) + [Delete Private Message](#delete-private-message)
- [Request](#request-11) - [Request](#request-11)
- [Response](#response-11) - [Response](#response-11)
- [HTTP](#http-12) - [HTTP](#http-12)
+ [Mark All As Read](#mark-all-as-read) + [Mark Private Message as Read](#mark-private-message-as-read)
- [Request](#request-12) - [Request](#request-12)
- [Response](#response-12) - [Response](#response-12)
- [HTTP](#http-13) - [HTTP](#http-13)
+ [Delete Account](#delete-account) + [Mark All As Read](#mark-all-as-read)
- [Request](#request-13) - [Request](#request-13)
- [Response](#response-13) - [Response](#response-13)
- [HTTP](#http-14) - [HTTP](#http-14)
+ [Add admin](#add-admin) + [Delete Account](#delete-account)
- [Request](#request-14) - [Request](#request-14)
- [Response](#response-14) - [Response](#response-14)
- [HTTP](#http-15) - [HTTP](#http-15)
+ [Ban user](#ban-user) + [Add admin](#add-admin)
- [Request](#request-15) - [Request](#request-15)
- [Response](#response-15) - [Response](#response-15)
- [HTTP](#http-16) - [HTTP](#http-16)
* [Site](#site) + [Ban user](#ban-user)
+ [List Categories](#list-categories)
- [Request](#request-16) - [Request](#request-16)
- [Response](#response-16) - [Response](#response-16)
- [HTTP](#http-17) - [HTTP](#http-17)
+ [Search](#search) + [User Join](#user-join)
- [Request](#request-17) - [Request](#request-17)
- [Response](#response-17) - [Response](#response-17)
- [HTTP](#http-18) - [HTTP](#http-18)
+ [Get Modlog](#get-modlog) * [Site](#site)
+ [List Categories](#list-categories)
- [Request](#request-18) - [Request](#request-18)
- [Response](#response-18) - [Response](#response-18)
- [HTTP](#http-19) - [HTTP](#http-19)
+ [Create Site](#create-site) + [Search](#search)
- [Request](#request-19) - [Request](#request-19)
- [Response](#response-19) - [Response](#response-19)
- [HTTP](#http-20) - [HTTP](#http-20)
+ [Edit Site](#edit-site) + [Get Modlog](#get-modlog)
- [Request](#request-20) - [Request](#request-20)
- [Response](#response-20) - [Response](#response-20)
- [HTTP](#http-21) - [HTTP](#http-21)
+ [Get Site](#get-site) + [Create Site](#create-site)
- [Request](#request-21) - [Request](#request-21)
- [Response](#response-21) - [Response](#response-21)
- [HTTP](#http-22) - [HTTP](#http-22)
+ [Transfer Site](#transfer-site) + [Edit Site](#edit-site)
- [Request](#request-22) - [Request](#request-22)
- [Response](#response-22) - [Response](#response-22)
- [HTTP](#http-23) - [HTTP](#http-23)
+ [Get Site Config](#get-site-config) + [Get Site](#get-site)
- [Request](#request-23) - [Request](#request-23)
- [Response](#response-23) - [Response](#response-23)
- [HTTP](#http-24) - [HTTP](#http-24)
+ [Save Site Config](#save-site-config) + [Transfer Site](#transfer-site)
- [Request](#request-24) - [Request](#request-24)
- [Response](#response-24) - [Response](#response-24)
- [HTTP](#http-25) - [HTTP](#http-25)
* [Community](#community) + [Get Site Config](#get-site-config)
+ [Get Community](#get-community)
- [Request](#request-25) - [Request](#request-25)
- [Response](#response-25) - [Response](#response-25)
- [HTTP](#http-26) - [HTTP](#http-26)
+ [Create Community](#create-community) + [Save Site Config](#save-site-config)
- [Request](#request-26) - [Request](#request-26)
- [Response](#response-26) - [Response](#response-26)
- [HTTP](#http-27) - [HTTP](#http-27)
+ [List Communities](#list-communities) * [Community](#community)
+ [Get Community](#get-community)
- [Request](#request-27) - [Request](#request-27)
- [Response](#response-27) - [Response](#response-27)
- [HTTP](#http-28) - [HTTP](#http-28)
+ [Ban from Community](#ban-from-community) + [Create Community](#create-community)
- [Request](#request-28) - [Request](#request-28)
- [Response](#response-28) - [Response](#response-28)
- [HTTP](#http-29) - [HTTP](#http-29)
+ [Add Mod to Community](#add-mod-to-community) + [List Communities](#list-communities)
- [Request](#request-29) - [Request](#request-29)
- [Response](#response-29) - [Response](#response-29)
- [HTTP](#http-30) - [HTTP](#http-30)
+ [Edit Community](#edit-community) + [Ban from Community](#ban-from-community)
- [Request](#request-30) - [Request](#request-30)
- [Response](#response-30) - [Response](#response-30)
- [HTTP](#http-31) - [HTTP](#http-31)
+ [Delete Community](#delete-community) + [Add Mod to Community](#add-mod-to-community)
- [Request](#request-31) - [Request](#request-31)
- [Response](#response-31) - [Response](#response-31)
- [HTTP](#http-32) - [HTTP](#http-32)
+ [Remove Community](#remove-community) + [Edit Community](#edit-community)
- [Request](#request-32) - [Request](#request-32)
- [Response](#response-32) - [Response](#response-32)
- [HTTP](#http-33) - [HTTP](#http-33)
+ [Follow Community](#follow-community) + [Delete Community](#delete-community)
- [Request](#request-33) - [Request](#request-33)
- [Response](#response-33) - [Response](#response-33)
- [HTTP](#http-34) - [HTTP](#http-34)
+ [Get Followed Communities](#get-followed-communities) + [Remove Community](#remove-community)
- [Request](#request-34) - [Request](#request-34)
- [Response](#response-34) - [Response](#response-34)
- [HTTP](#http-35) - [HTTP](#http-35)
+ [Transfer Community](#transfer-community) + [Follow Community](#follow-community)
- [Request](#request-35) - [Request](#request-35)
- [Response](#response-35) - [Response](#response-35)
- [HTTP](#http-36) - [HTTP](#http-36)
* [Post](#post) + [Get Followed Communities](#get-followed-communities)
+ [Create Post](#create-post)
- [Request](#request-36) - [Request](#request-36)
- [Response](#response-36) - [Response](#response-36)
- [HTTP](#http-37) - [HTTP](#http-37)
+ [Get Post](#get-post) + [Transfer Community](#transfer-community)
- [Request](#request-37) - [Request](#request-37)
- [Response](#response-37) - [Response](#response-37)
- [HTTP](#http-38) - [HTTP](#http-38)
+ [Get Posts](#get-posts) + [Community Join](#community-join)
- [Request](#request-38) - [Request](#request-38)
- [Response](#response-38) - [Response](#response-38)
- [HTTP](#http-39) - [HTTP](#http-39)
+ [Create Post Like](#create-post-like) * [Post](#post)
+ [Create Post](#create-post)
- [Request](#request-39) - [Request](#request-39)
- [Response](#response-39) - [Response](#response-39)
- [HTTP](#http-40) - [HTTP](#http-40)
+ [Edit Post](#edit-post) + [Get Post](#get-post)
- [Request](#request-40) - [Request](#request-40)
- [Response](#response-40) - [Response](#response-40)
- [HTTP](#http-41) - [HTTP](#http-41)
+ [Delete Post](#delete-post) + [Get Posts](#get-posts)
- [Request](#request-41) - [Request](#request-41)
- [Response](#response-41) - [Response](#response-41)
- [HTTP](#http-42) - [HTTP](#http-42)
+ [Remove Post](#remove-post) + [Create Post Like](#create-post-like)
- [Request](#request-42) - [Request](#request-42)
- [Response](#response-42) - [Response](#response-42)
- [HTTP](#http-43) - [HTTP](#http-43)
+ [Lock Post](#lock-post) + [Edit Post](#edit-post)
- [Request](#request-43) - [Request](#request-43)
- [Response](#response-43) - [Response](#response-43)
- [HTTP](#http-44) - [HTTP](#http-44)
+ [Sticky Post](#sticky-post) + [Delete Post](#delete-post)
- [Request](#request-44) - [Request](#request-44)
- [Response](#response-44) - [Response](#response-44)
- [HTTP](#http-45) - [HTTP](#http-45)
+ [Save Post](#save-post) + [Remove Post](#remove-post)
- [Request](#request-45) - [Request](#request-45)
- [Response](#response-45) - [Response](#response-45)
- [HTTP](#http-46) - [HTTP](#http-46)
* [Comment](#comment) + [Lock Post](#lock-post)
+ [Create Comment](#create-comment)
- [Request](#request-46) - [Request](#request-46)
- [Response](#response-46) - [Response](#response-46)
- [HTTP](#http-47) - [HTTP](#http-47)
+ [Edit Comment](#edit-comment) + [Sticky Post](#sticky-post)
- [Request](#request-47) - [Request](#request-47)
- [Response](#response-47) - [Response](#response-47)
- [HTTP](#http-48) - [HTTP](#http-48)
+ [Delete Comment](#delete-comment) + [Save Post](#save-post)
- [Request](#request-48) - [Request](#request-48)
- [Response](#response-48) - [Response](#response-48)
- [HTTP](#http-49) - [HTTP](#http-49)
+ [Remove Comment](#remove-comment) + [Post Join](#post-join)
- [Request](#request-49) - [Request](#request-49)
- [Response](#response-49) - [Response](#response-49)
- [HTTP](#http-50) - [HTTP](#http-50)
+ [Mark Comment as Read](#mark-comment-as-read) * [Comment](#comment)
+ [Create Comment](#create-comment)
- [Request](#request-50) - [Request](#request-50)
- [Response](#response-50) - [Response](#response-50)
- [HTTP](#http-51) - [HTTP](#http-51)
+ [Save Comment](#save-comment) + [Edit Comment](#edit-comment)
- [Request](#request-51) - [Request](#request-51)
- [Response](#response-51) - [Response](#response-51)
- [HTTP](#http-52) - [HTTP](#http-52)
+ [Create Comment Like](#create-comment-like) + [Delete Comment](#delete-comment)
- [Request](#request-52) - [Request](#request-52)
- [Response](#response-52) - [Response](#response-52)
- [HTTP](#http-53) - [HTTP](#http-53)
+ [Remove Comment](#remove-comment)
- [Request](#request-53)
- [Response](#response-53)
- [HTTP](#http-54)
+ [Get Comments](#get-comments)
- [Request](#request-54)
- [Response](#response-54)
- [HTTP](#http-55)
+ [Mark Comment as Read](#mark-comment-as-read)
- [Request](#request-55)
- [Response](#response-55)
- [HTTP](#http-56)
+ [Save Comment](#save-comment)
- [Request](#request-56)
- [Response](#response-56)
- [HTTP](#http-57)
+ [Create Comment Like](#create-comment-like)
- [Request](#request-57)
- [Response](#response-57)
- [HTTP](#http-58)
* [RSS / Atom feeds](#rss--atom-feeds) * [RSS / Atom feeds](#rss--atom-feeds)
+ [All](#all) + [All](#all)
+ [Community](#community-1) + [Community](#community-1)
@ -249,7 +269,7 @@
- <code>Option<***SomeType***></code> designates an option which may be omitted in requests and not be present in responses. It will be of type ***SomeType***. - <code>Option<***SomeType***></code> designates an option which may be omitted in requests and not be present in responses. It will be of type ***SomeType***.
- <code>Vec<***SomeType***></code> is a list which contains objects of type ***SomeType***. - <code>Vec<***SomeType***></code> is a list which contains objects of type ***SomeType***.
- `chrono::NaiveDateTime` is a timestamp string in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Timestamps will be UTC. - `chrono::NaiveDateTime` is a timestamp string in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Timestamps will be UTC.
- Other data types are listed [here](../server/src/db). - Other data types are listed [here](../src/db).
## Basic usage ## Basic usage
@ -261,6 +281,12 @@ Connect to <code>ws://***host***/api/v1/ws</code> to get started.
If the ***`host`*** supports secure connections, you can use <code>wss://***host***/api/v1/ws</code>. If the ***`host`*** supports secure connections, you can use <code>wss://***host***/api/v1/ws</code>.
To receive websocket messages, you must join a room / context. The three available are:
- [UserJoin](#user-join). Receives replies, private messages, etc.
- [PostJoin](#post-join). Receives new comments on a post.
- [CommunityJoin](#community-join). Receives front page / community posts.
#### Testing with Websocat #### Testing with Websocat
[Websocat link](https://github.com/vi/websocat) [Websocat link](https://github.com/vi/websocat)
@ -839,6 +865,29 @@ Marks all user replies and mentions as read.
`POST /user/ban` `POST /user/ban`
#### User Join
##### Request
```rust
{
op: "UserJoin",
data: {
auth: String
}
}
```
##### Response
```rust
{
op: "UserJoin",
data: {
joined: bool,
}
}
```
##### HTTP
`POST /user/join`
### Site ### Site
#### List Categories #### List Categories
##### Request ##### Request
@ -1387,6 +1436,32 @@ Only admins can remove a community.
`POST /community/transfer` `POST /community/transfer`
#### Community Join
The main / frontpage community is `community_id: 0`.
##### Request
```rust
{
op: "CommunityJoin",
data: {
community_id: i32
}
}
```
##### Response
```rust
{
op: "CommunityJoin",
data: {
joined: bool,
}
}
```
##### HTTP
`POST /community/join`
### Post ### Post
#### Create Post #### Create Post
##### Request ##### Request
@ -1671,6 +1746,29 @@ Only admins and mods can sticky a post.
`POST /post/save` `POST /post/save`
#### Post Join
##### Request
```rust
{
op: "PostJoin",
data: {
post_id: i32
}
}
```
##### Response
```rust
{
op: "PostJoin",
data: {
joined: bool,
}
}
```
##### HTTP
`POST /post/join`
### Comment ### Comment
#### Create Comment #### Create Comment
##### Request ##### Request
@ -1787,6 +1885,38 @@ Only a mod or admin can remove the comment.
`POST /comment/remove` `POST /comment/remove`
#### Get Comments
Comment listing types are `All, Subscribed, Community`
##### Request
```rust
{
op: "GetComments",
data: {
type_: String,
sort: String,
page: Option<i64>,
limit: Option<i64>,
community_id: Option<i32>,
community_name: Option<String>,
auth: Option<String>
}
}
```
##### Response
```rust
{
op: "GetComments",
data: {
comments: Vec<CommentView>,
}
}
```
##### HTTP
`GET /comment/list`
#### Mark Comment as Read #### Mark Comment as Read
Only the recipient can do this. Only the recipient can do this.

View file

@ -29,7 +29,7 @@ ask_to_init_db() {
done done
if [ "$init_db_final" = 1 ] if [ "$init_db_final" = 1 ]
then then
source ./server/db-init.sh source ./db-init.sh
read -n 1 -s -r -p "Press ANY KEY to continue execution of this script, press CTRL+C to quit..." read -n 1 -s -r -p "Press ANY KEY to continue execution of this script, press CTRL+C to quit..."
echo echo
fi fi

View file

@ -68,6 +68,7 @@ pub struct GetComments {
pub page: Option<i64>, pub page: Option<i64>,
pub limit: Option<i64>, pub limit: Option<i64>,
pub community_id: Option<i32>, pub community_id: Option<i32>,
pub community_name: Option<String>,
pub auth: Option<String>, pub auth: Option<String>,
} }

View file

@ -129,3 +129,13 @@ pub struct TransferCommunity {
pub user_id: i32, pub user_id: i32,
pub auth: String, pub auth: String,
} }
#[derive(Deserialize, Debug)]
pub struct CommunityJoin {
pub community_id: i32,
}
#[derive(Serialize, Clone)]
pub struct CommunityJoinResponse {
pub joined: bool,
}

View file

@ -1,7 +1,7 @@
extern crate serde;
extern crate log;
extern crate diesel;
extern crate actix_web; extern crate actix_web;
extern crate diesel;
extern crate log;
extern crate serde;
pub mod comment; pub mod comment;
pub mod community; pub mod community;
@ -9,22 +9,22 @@ pub mod post;
pub mod site; pub mod site;
pub mod user; pub mod user;
use lemmy_db::comment::Comment;
use lemmy_db::user::User_;
use lemmy_db::post::Post;
use lemmy_db::user_mention::{UserMentionForm, UserMention};
use log::error;
use lemmy_db::{Crud, DbPool};
use lemmy_utils::utils::MentionData;
use lemmy_utils::settings::Settings;
use lemmy_utils::email::send_email;
use diesel::PgConnection; use diesel::PgConnection;
use lemmy_utils::LemmyError; use lemmy_db::{
comment::Comment,
post::Post,
user::User_,
user_mention::{UserMention, UserMentionForm},
Crud,
DbPool,
};
use lemmy_utils::{email::send_email, settings::Settings, utils::MentionData, LemmyError};
use log::error;
pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError> pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError>
where where
F: FnOnce(&diesel::PgConnection) -> T + Send + 'static, F: FnOnce(&diesel::PgConnection) -> T + Send + 'static,
T: Send + 'static, T: Send + 'static,
{ {
let pool = pool.clone(); let pool = pool.clone();
let res = actix_web::web::block(move || { let res = actix_web::web::block(move || {
@ -32,7 +32,7 @@ pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError>
let res = (f)(&conn); let res = (f)(&conn);
Ok(res) as Result<_, LemmyError> Ok(res) as Result<_, LemmyError>
}) })
.await?; .await?;
Ok(res) Ok(res)
} }
@ -49,7 +49,7 @@ pub async fn send_local_notifs(
let ids = blocking(pool, move |conn| { let ids = blocking(pool, move |conn| {
do_send_local_notifs(conn, &mentions, &comment, &user2, &post, do_send_email) do_send_local_notifs(conn, &mentions, &comment, &user2, &post, do_send_email)
}) })
.await?; .await?;
Ok(ids) Ok(ids)
} }

View file

@ -103,3 +103,13 @@ pub struct SavePost {
pub save: bool, pub save: bool,
pub auth: String, pub auth: String,
} }
#[derive(Deserialize, Debug)]
pub struct PostJoin {
pub post_id: i32,
}
#[derive(Serialize, Clone)]
pub struct PostJoinResponse {
pub joined: bool,
}

View file

@ -235,5 +235,5 @@ pub struct UserJoin {
#[derive(Serialize, Clone)] #[derive(Serialize, Clone)]
pub struct UserJoinResponse { pub struct UserJoinResponse {
pub user_id: i32, pub joined: bool,
} }

View file

@ -130,6 +130,7 @@ pub struct CommentQueryBuilder<'a> {
listing_type: ListingType, listing_type: ListingType,
sort: &'a SortType, sort: &'a SortType,
for_community_id: Option<i32>, for_community_id: Option<i32>,
for_community_name: Option<String>,
for_post_id: Option<i32>, for_post_id: Option<i32>,
for_creator_id: Option<i32>, for_creator_id: Option<i32>,
search_term: Option<String>, search_term: Option<String>,
@ -151,6 +152,7 @@ impl<'a> CommentQueryBuilder<'a> {
listing_type: ListingType::All, listing_type: ListingType::All,
sort: &SortType::New, sort: &SortType::New,
for_community_id: None, for_community_id: None,
for_community_name: None,
for_post_id: None, for_post_id: None,
for_creator_id: None, for_creator_id: None,
search_term: None, search_term: None,
@ -186,6 +188,11 @@ impl<'a> CommentQueryBuilder<'a> {
self self
} }
pub fn for_community_name<T: MaybeOptional<String>>(mut self, for_community_name: T) -> Self {
self.for_community_name = for_community_name.get_optional();
self
}
pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self { pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
self.search_term = search_term.get_optional(); self.search_term = search_term.get_optional();
self self
@ -231,6 +238,10 @@ impl<'a> CommentQueryBuilder<'a> {
query = query.filter(community_id.eq(for_community_id)); query = query.filter(community_id.eq(for_community_id));
} }
if let Some(for_community_name) = self.for_community_name {
query = query.filter(community_name.eq(for_community_name));
}
if let Some(for_post_id) = self.for_post_id { if let Some(for_post_id) = self.for_post_id {
query = query.filter(post_id.eq(for_post_id)); query = query.filter(post_id.eq(for_post_id));
}; };

View file

@ -523,36 +523,36 @@ joinable!(user_mention -> comment (comment_id));
joinable!(user_mention -> user_ (recipient_id)); joinable!(user_mention -> user_ (recipient_id));
allow_tables_to_appear_in_same_query!( allow_tables_to_appear_in_same_query!(
activity, activity,
category, category,
comment, comment,
comment_aggregates_fast, comment_aggregates_fast,
comment_like, comment_like,
comment_saved, comment_saved,
community, community,
community_aggregates_fast, community_aggregates_fast,
community_follower, community_follower,
community_moderator, community_moderator,
community_user_ban, community_user_ban,
mod_add, mod_add,
mod_add_community, mod_add_community,
mod_ban, mod_ban,
mod_ban_from_community, mod_ban_from_community,
mod_lock_post, mod_lock_post,
mod_remove_comment, mod_remove_comment,
mod_remove_community, mod_remove_community,
mod_remove_post, mod_remove_post,
mod_sticky_post, mod_sticky_post,
password_reset_request, password_reset_request,
post, post,
post_aggregates_fast, post_aggregates_fast,
post_like, post_like,
post_read, post_read,
post_saved, post_saved,
private_message, private_message,
site, site,
user_, user_,
user_ban, user_ban,
user_fast, user_fast,
user_mention, user_mention,
); );

View file

@ -13,7 +13,6 @@ pub struct Settings {
pub bind: IpAddr, pub bind: IpAddr,
pub port: u16, pub port: u16,
pub jwt_secret: String, pub jwt_secret: String,
pub front_end_dir: String,
pub pictrs_url: String, pub pictrs_url: String,
pub rate_limit: RateLimitConfig, pub rate_limit: RateLimitConfig,
pub email: Option<EmailConfig>, pub email: Option<EmailConfig>,
@ -88,7 +87,7 @@ impl Settings {
/// added to the config. /// added to the config.
/// ///
/// Note: The env var `LEMMY_DATABASE_URL` is parsed in /// Note: The env var `LEMMY_DATABASE_URL` is parsed in
/// `server/lemmy_db/src/lib.rs::get_database_url_from_env()` /// `lemmy_db/src/lib.rs::get_database_url_from_env()`
fn init() -> Result<Self, ConfigError> { fn init() -> Result<Self, ConfigError> {
let mut s = Config::new(); let mut s = Config::new();

Some files were not shown because too many files have changed in this diff Show more