Wdróż aplikację Lemmy na Pethost jednym kliknięciem
Agregator linków i forum dla fediwersum
Co się dzieje
- Logujesz się do Pethost albo zakładasz konto, kluczem dostępu, przez GitHub albo Google.
- Nie masz jeszcze maszyny? Wybierasz plan, a my ją dla ciebie przygotowujemy. Link czeka w twojej przeglądarce, aż będzie gotowa.
- Okno „Nowy projekt” otwiera się na tej aplikacji. Wypełniasz to, o co prosi, i klikasz „Utwórz projekt”: Hasło administratora.
- Za minutę czy dwie aplikacja działa pod własnym adresem z HTTPS. Jej sekrety są tworzone losowo, a dane trafiają do nocnego backupu.
- To projekt jak każdy inny: jego compose.yaml, .env, logi i terminal są w panelu, a twój agent może go zmienić, cofnąć do wcześniejszej wersji albo przywrócić.
Pierwsze kroki
Zaloguj się jako admin z hasłem podanym przy tworzeniu projektu; pierwsze uruchomienie trwa minutę lub dwie. Nowe konta czekają na twoje zatwierdzenie: Registration Mode jest w Admin Settings. Hasło zmienisz w ustawieniach samej aplikacji Lemmy: to z .env jest odczytywane tylko raz. Adres to nazwa instancji we fediwersum, więc go zachowaj.
Co uruchamia
Szablon to ten compose.yaml i zmienne, które zapisuje do .env projektu. Pethost uruchamia plik dokładnie tak, jak jest napisany.
services:
# Lemmy's own front door: a fediverse server asks for a page as ActivityPub
# JSON, and those requests, the API's and every non-GET go to the backend;
# the rest goes to the UI.
proxy:
image: nginx:1-alpine
restart: unless-stopped
configs:
- source: nginx
target: /etc/nginx/nginx.conf
depends_on:
- lemmy
- lemmy-ui
lemmy:
image: dessalines/lemmy:0.19.20
restart: unless-stopped
environment:
RUST_LOG: warn
configs:
- source: lemmy
target: /config/config.hjson
depends_on:
db:
condition: service_healthy
pictrs:
condition: service_started
# The first start runs the migrations and makes the admin before it listens.
healthcheck:
test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://127.0.0.1:8536/api/v3/site"]
interval: 10s
timeout: 5s
retries: 5
start_period: 180s
lemmy-ui:
image: dessalines/lemmy-ui:0.19.20
restart: unless-stopped
environment:
LEMMY_UI_LEMMY_INTERNAL_HOST: lemmy:8536
LEMMY_UI_LEMMY_EXTERNAL_HOST: ${HOST}
LEMMY_UI_HTTPS: "true"
depends_on:
lemmy:
condition: service_healthy
# The image's own check runs once a minute; this one answers in ten seconds.
healthcheck:
test: ["CMD-SHELL", "curl -ILfSs http://localhost:1234/ > /dev/null || exit 1"]
interval: 10s
timeout: 10s
retries: 3
start_period: 30s
pictrs:
image: asonix/pictrs:0.5
restart: unless-stopped
environment:
PICTRS__SERVER__API_KEY: ${PICTRS_API_KEY}
# Kept light: no video transcoding, and small animations, as Lemmy's docs set them.
PICTRS__MEDIA__VIDEO__ENABLE: "false"
PICTRS__MEDIA__ANIMATION__MAX_WIDTH: 256
PICTRS__MEDIA__ANIMATION__MAX_HEIGHT: 256
PICTRS__MEDIA__ANIMATION__MAX_AREA: 65536
PICTRS__MEDIA__ANIMATION__MAX_FRAME_COUNT: 400
volumes:
- pictrs:/mnt
db:
image: postgres:18-alpine
restart: unless-stopped
environment:
POSTGRES_DB: lemmy
POSTGRES_USER: lemmy
POSTGRES_PASSWORD: ${DB_PASSWORD}
# Lemmy's docs raise Docker's 64 MB: big queries fail with "could not resize shared memory segment".
shm_size: 1g
volumes:
- db:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U lemmy -d lemmy"]
interval: 5s
timeout: 5s
retries: 12
start_period: 30s
configs:
# Lemmy reads its settings from this file alone. `setup` makes the admin at the
# first start, so no setup page is left open; the password is a multiline
# string, which Hjson takes as written, quotes and backslashes included.
lemmy:
content: |
{
hostname: "${HOST}"
database: {
host: db
password: "${DB_PASSWORD}"
}
pictrs: {
url: "http://pictrs:8080/"
api_key: "${PICTRS_API_KEY}"
# Thumbnails of linked pages stay where they are, not copied into pict-rs.
image_mode: "None"
}
setup: {
admin_username: admin
admin_password:
'''
${ADMIN_PASSWORD}
'''
site_name: Lemmy
}
}
# Lemmy's nginx_internal.conf (lemmy-ansible); $$ is a $ to Compose.
nginx:
content: |
worker_processes auto;
events {
worker_connections 1024;
}
http {
# Docker's DNS, asked at each request, so that a recreated container is found.
resolver 127.0.0.11 valid=5s;
# The visitor's address, from the machine's proxy.
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
map "$$request_method:$$http_accept" $$proxpass {
default "http://lemmy-ui:1234";
"~^(?:GET|HEAD):.*?application\/(?:activity|ld)\+json" "http://lemmy:8536";
"~^(?!(GET|HEAD)).*:" "http://lemmy:8536";
}
server {
set $$lemmy_ui "lemmy-ui:1234";
set $$lemmy "lemmy:8536";
listen 8536;
server_name localhost;
server_tokens off;
# Uploads go to pict-rs through the backend.
client_max_body_size 20M;
proxy_set_header Host $$http_host;
proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for;
location / {
proxy_pass $$proxpass;
rewrite ^(.+)/+$$ $$1 permanent;
}
location = /.well-known/security.txt {
proxy_pass "http://$$lemmy_ui";
}
location ~ ^/(api|pictrs|feeds|nodeinfo|.well-known|version|sitemap.xml) {
proxy_pass "http://$$lemmy";
}
}
}
volumes:
pictrs:
db: