diff --git a/env.production b/env.production index 8739e37..0f083c1 100644 --- a/env.production +++ b/env.production @@ -9,3 +9,4 @@ GRAFANA_HOSTNAME=dashboard.hackerspace.zone GITEA_HOSTNAME=git.hackerspace.zone MATRIX_HOSTNAME=matrix.hackerspace.zone MOBILIZON_HOSTNAME=events.hackerspace.zone +PIXELFED_HOSTNAME=pixelfed.hackerspace.zone diff --git a/nginx/certbot-renew b/nginx/certbot-renew index 7abc555..45df1a2 100755 --- a/nginx/certbot-renew +++ b/nginx/certbot-renew @@ -7,7 +7,7 @@ cd "$DIRNAME" source ../env.production source ./env.production -domain_args="-d $DOMAIN_NAME,$KEYCLOAK_HOSTNAME,$HEDGEDOC_HOSTNAME,$MASTODON_HOSTNAME,$NEXTCLOUD_HOSTNAME,$GRAFANA_HOSTNAME,$MATRIX_HOSTNAME,$GITEA_HOSTNAME,$MOBILIZON_HOSTNAME" +domain_args="-d $DOMAIN_NAME,$KEYCLOAK_HOSTNAME,$HEDGEDOC_HOSTNAME,$MASTODON_HOSTNAME,$NEXTCLOUD_HOSTNAME,$GRAFANA_HOSTNAME,$MATRIX_HOSTNAME,$GITEA_HOSTNAME,$MOBILIZON_HOSTNAME,$PIXELFED_HOSTNAME" rsa_key_size=2048 set -x diff --git a/nginx/nginx/templates/pixelfed.conf.template b/nginx/nginx/templates/pixelfed.conf.template new file mode 100644 index 0000000..d3dbb74 --- /dev/null +++ b/nginx/nginx/templates/pixelfed.conf.template @@ -0,0 +1,30 @@ +server { + server_name ${PIXELFED_HOSTNAME}; + client_max_body_size 128m; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + gzip on; + gzip_disable "msie6"; + + proxy_read_timeout 1800s; + + location / { + proxy_pass http://host.docker.internal:8090; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + listen 443 ssl; + ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem; + include /etc/nginx/includes/options-ssl-nginx.conf; + include /etc/nginx/includes/challenge.conf; + ssl_dhparam /etc/nginx/includes/ssl-dhparams.pem; +} diff --git a/pixelfed/app.php b/pixelfed/app.php new file mode 100644 index 0000000..f2801ad --- /dev/null +++ b/pixelfed/app.php @@ -0,0 +1,55 @@ +singleton( + Illuminate\Contracts\Http\Kernel::class, + App\Http\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +/* +|-------------------------------------------------------------------------- +| Return The Application +|-------------------------------------------------------------------------- +| +| This script returns the application instance. The instance is given to +| the calling script so we can separate the building of the instances +| from the actual running of the application and sending responses. +| +*/ + +return $app; diff --git a/pixelfed/docker-compose.yml b/pixelfed/docker-compose.yml new file mode 100644 index 0000000..0f52828 --- /dev/null +++ b/pixelfed/docker-compose.yml @@ -0,0 +1,73 @@ +--- +version: '3' + +services: +## App and Worker + app: + image: osresearch/pixelfed + restart: unless-stopped + env_file: + - ../env.production + - env.production + - ../data/pixelfed/env.secrets + volumes: + - ../data/pixelfed/app-storage:/var/www/storage + - ../data/pixelfed/app-bootstrap:/var/www/bootstrap + - ../data/pixelfed/env.secrets:/var/www/.env + networks: + - external + - internal + ports: + - "8090:80" + depends_on: + - db + - redis + + worker: + image: osresearch/pixelfed + restart: unless-stopped + env_file: + - ../env.production + - env.production + - ../data/pixelfed/env.secrets + volumes: + - ../data/pixelfed/app-storage:/var/www/storage + - ../data/pixelfed/app-bootstrap:/var/www/bootstrap + - ../data/pixelfed/env.secrets:/var/www/.env + networks: + - external + - internal + command: gosu www-data php artisan horizon + depends_on: + - db + - redis + +## DB and Cache + db: + image: mysql:8.0 + restart: unless-stopped + networks: + - internal + command: --default-authentication-plugin=mysql_native_password + env_file: + - ../env.production + - env.production + volumes: + - "../data/pixelfed/db-data:/var/lib/mysql" + + redis: + image: redis:5-alpine + restart: unless-stopped + env_file: + - ../env.production + - env.production + volumes: + - "../data/pixelfed/redis-data:/data" + networks: + - internal + +networks: + internal: + internal: true + external: + driver: bridge diff --git a/pixelfed/env.production b/pixelfed/env.production new file mode 100644 index 0000000..d132668 --- /dev/null +++ b/pixelfed/env.production @@ -0,0 +1,157 @@ +## Crypto +APP_KEY=base64:fjwyqPkDUoYkQNVhkjsPTj5TkO6IaNb3NXmIobJJ5nk= + +## General Settings +APP_ENV=production +APP_DEBUG=true + +# domain name specifics are passed in env.secrets +# APP_NAME="Pixelfed Prod (Testing)" +# APP_URL="https://pixelfed.hackerspace.zone" +# APP_DOMAIN="pixelfed.hackerspace.zone" +# ADMIN_DOMAIN="pixelfed.hackerspace.zone" +# SESSION_DOMAIN="pixelfed.hackerspace.zone" + +OPEN_REGISTRATION=true +ENFORCE_EMAIL_VERIFICATION=false +PF_MAX_USERS=1000 +OAUTH_ENABLED=false + +APP_TIMEZONE=UTC +APP_LOCALE=en + +## Pixelfed Tweaks +LIMIT_ACCOUNT_SIZE=true +MAX_ACCOUNT_SIZE=1000000 +MAX_PHOTO_SIZE=15000 +MAX_AVATAR_SIZE=2000 +MAX_CAPTION_LENGTH=500 +MAX_BIO_LENGTH=125 +MAX_NAME_LENGTH=30 +MAX_ALBUM_LENGTH=4 +IMAGE_QUALITY=80 +PF_OPTIMIZE_IMAGES=true +PF_OPTIMIZE_VIDEOS=true +ADMIN_ENV_EDITOR=false +ACCOUNT_DELETION=true +ACCOUNT_DELETE_AFTER=false +MAX_LINKS_PER_POST=0 + +## Instance +# INSTANCE_DESCRIPTION="hackerspace.zone pixelfed test" +INSTANCE_PUBLIC_HASHTAGS=false +#INSTANCE_CONTACT_EMAIL= +INSTANCE_PUBLIC_LOCAL_TIMELINE=true +INSTANCE_DISCOVER_PUBLIC=true +#BANNED_USERNAMES= +STORIES_ENABLED=false +RESTRICTED_INSTANCE=false + +## Mail config is in env.secrets +# MAIL_DRIVER=log +# MAIL_HOST=smtp.mailtrap.io +# MAIL_PORT=2525 +# MAIL_FROM_ADDRESS="pixelfed@example.com" +# MAIL_FROM_NAME="Pixelfed" +# MAIL_USERNAME=null +# MAIL_PASSWORD=null +# MAIL_ENCRYPTION=null + +## Databases (MySQL) +DB_CONNECTION=mysql +DB_DATABASE=pixelfed_prod +DB_HOST=db +DB_PASSWORD=pixelfed_db_pass +DB_PORT=3306 +DB_USERNAME=pixelfed +# pass the same values to the db itself +MYSQL_DATABASE=pixelfed_prod +MYSQL_PASSWORD=pixelfed_db_pass +MYSQL_RANDOM_ROOT_PASSWORD=true +MYSQL_USER=pixelfed + +## Databases (Postgres) +#DB_CONNECTION=pgsql +#DB_HOST=postgres +#DB_PORT=5432 +#DB_DATABASE=pixelfed +#DB_USERNAME=postgres +#DB_PASSWORD=postgres + +## Cache (Redis) +REDIS_CLIENT=phpredis +REDIS_SCHEME=tcp +REDIS_HOST=redis +REDIS_PASSWORD=redis_password +REDIS_PORT=6379 +REDIS_DATABASE=0 + +## EXPERIMENTS +EXP_LC=false +EXP_REC=false +EXP_LOOPS=false + +## ActivityPub Federation +ACTIVITY_PUB=true +AP_REMOTE_FOLLOW=true +AP_SHAREDINBOX=true +AP_INBOX=true +AP_OUTBOX=true +ATOM_FEEDS=true +NODEINFO=true +WEBFINGER=true + +## S3 +FILESYSTEM_DRIVER=local +FILESYSTEM_CLOUD=s3 +PF_ENABLE_CLOUD=false +#AWS_ACCESS_KEY_ID= +#AWS_SECRET_ACCESS_KEY= +#AWS_DEFAULT_REGION= +#AWS_BUCKET= +#AWS_URL= +#AWS_ENDPOINT= +#AWS_USE_PATH_STYLE_ENDPOINT=false + +## Horizon +HORIZON_DARKMODE=true + +## COSTAR - Confirm Object Sentiment Transform and Reduce +PF_COSTAR_ENABLED=false + +# Media +MEDIA_EXIF_DATABASE=false + +## Logging +LOG_CHANNEL=stderr + +## Image +IMAGE_DRIVER=imagick + +## Broadcasting +BROADCAST_DRIVER=log # log driver for local development + +## Cache +CACHE_DRIVER=redis + +## Purify +RESTRICT_HTML_TYPES=true + +## Queue +QUEUE_DRIVER=redis + +## Session +SESSION_DRIVER=redis + +## Trusted Proxy +TRUST_PROXIES="*" + +## Passport +#PASSPORT_PRIVATE_KEY= +#PASSPORT_PUBLIC_KEY= + +## OIDC for logins passed in in env.secrets +# OIDC_CLIENT_ID=pixelfed +# OIDC_CLIENT_SECRET=F55hjj2FBPnnuW7nD80LjwS9sVYXm4fB +# OIDC_PROVIDER_URL=https://login.hackerspace.zone/realms/hackerspace +OIDC_PROVIDER_NAME=oidc diff --git a/pixelfed/setup b/pixelfed/setup new file mode 100755 index 0000000..b8f3e9e --- /dev/null +++ b/pixelfed/setup @@ -0,0 +1,95 @@ +#!/bin/bash +MODULE=pixelfed +die() { echo >&2 "$MODULE: $@" ; exit 1 ; } +info() { echo >&2 "$MODULE: $@" ; } + +DIRNAME="$(dirname $0)" +cd "$DIRNAME" +source ../env.production || die "no top level env?" +source env.production || die "no local env?" +source ../env.smtp 2>/dev/null + +DATA="../data/$MODULE" +SECRETS="$DATA/env.secrets" + +if [ -r "$SECRETS" ]; then + docker-compose up -d || die "unable to start" + exit 0 +fi + +docker-compose down 2>/dev/null + +CLIENT_SECRET="$(openssl rand -hex 20)" + +mkdir -p "$(dirname "$SECRETS")" +cat < "$SECRETS" +# DO NOT CHECK IN +INSTANCE_DESCRIPTION="${DOMAIN_NAME} pixelfed" +OIDC_CLIENT_ID=$MODULE +OIDC_CLIENT_SECRET=${CLIENT_SECRET} +OIDC_PROVIDER_URL=https://${KEYCLOAK_HOSTNAME}/realms/${REALM} +APP_NAME="${DOMAIN_NAME} Pixelfed" +APP_URL="https://${PIXELFED_HOSTNAME}" +APP_DOMAIN="${PIXELFED_HOSTNAME}" +ADMIN_DOMAIN="${PIXELFED_HOSTNAME}" +SESSION_DOMAIN="${PIXELFED_HOSTNAME}" +EOF + +if [ -n "$SMTP_SERVER" ]; then + cat <> "$SECRETS" +MAIL_DRIVER=log +MAIL_HOST=${SMTP_SERVER} +MAIL_PORT=${SMTP_PORT} +MAIL_FROM_ADDRESS="pixelfed@${DOMAIN_NAME}" +MAIL_FROM_NAME="Pixelfed" +MAIL_USERNAME="${SMTP_USER}" +MAIL_PASSWORD="${SMTP_PASSWORD}" +# MAIL_ENCRYPTION=null +EOF +fi + +chown www-data:www-data "$SECRETS" + +../keycloak/client-delete $MODULE 2>/dev/null + +../keycloak/client-create <