Refactored bluesky

This commit is contained in:
Kevin Veen-Birkenbach 2025-02-06 23:59:53 +01:00
parent c2f97cde59
commit f0760d3969
29 changed files with 92 additions and 326 deletions

View File

@ -36,6 +36,9 @@ defaults_applications:
administrator_email: "{{administrator_email}}" administrator_email: "{{administrator_email}}"
pds: pds:
version: "latest" version: "latest"
#jwt_secret: # Needs to be defined in inventory file
#plc_rotation_key_k256_private_key_hex: # Needs to be defined in inventory file
#admin_password: # Needs to be defined in inventory file
## Friendica ## Friendica
friendica: friendica:

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -4,16 +4,16 @@
## Setup ## Setup
### Set variables ### Set variables
#### bluesky_pds_jwt_secret #### applications.bluesky.pds.jwt_secret
```bash ```bash
openssl rand -base64 64 | tr -d '\n' openssl rand -base64 64 | tr -d '\n'
``` ```
for for
#### bluesky_pds_plc_rotation_key_k256_private_key_hex #### applications.bluesky.pds.plc_rotation_key_k256_private_key_hex
openssl rand -hex 32 openssl rand -hex 32
#### bluesky_pds_admin_password #### applications.bluesky.pds.admin_password
openssl rand -base64 16 openssl rand -base64 16
### Configure DNS ### Configure DNS
@ -58,4 +58,4 @@ Initial setup keine top level domain
- https://github.com/bluesky-social/pds/issues/52 - https://github.com/bluesky-social/pds/issues/52
- https://github.com/lhaig/pdsadmin - https://github.com/lhaig/pdsadmin
- https://github.com/bluesky-social/pds/issues/147 - https://github.com/bluesky-social/pds/issues/147
- - https://docs.bsky.app/docs/advanced-guides/oauth-client

View File

@ -50,8 +50,5 @@
version: "main" version: "main"
notify: docker compose project build and setup notify: docker compose project build and setup
- name: add docker-compose.yml - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: docker-compose.yml.j2
dest: "{{docker_compose.directories.instance}}docker-compose.yml"
notify: docker compose project build and setup

View File

@ -1,33 +1,10 @@
services: services:
pds: pds:
image: "ghcr.io/bluesky-social/pds:{{applications.bluesky.pds.version}}" image: "ghcr.io/bluesky-social/pds:{{applications.bluesky.pds.version}}"
restart: {{docker_restart_policy}} {% include 'roles/docker-compose/templates/services/base.yml.j2' %}
volumes: volumes:
- pds_data:/pds - pds_data:/pds
- {{pdsadmin_file_path}}:/usr/local/bin/pdsadmin:ro - {{pdsadmin_file_path}}:/usr/local/bin/pdsadmin:ro
environment:
# Geben Sie hier Ihre Domain und Konfigurationsdetails an
PDS_HOSTNAME: "{{domains.api}}"
PDS_ADMIN_EMAIL: "{{applications.bluesky.administrator_email}}"
PDS_SERVICE_DID: "did:web:{{domain_api}}"
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
PDS_SERVICE_HANDLE_DOMAINS: ".{{primary_domain}}"
PDS_JWT_SECRET: "{{bluesky_pds_jwt_secret}}"
PDS_ADMIN_PASSWORD: "{{bluesky_pds_admin_password}}"
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: "{{bluesky_pds_plc_rotation_key_k256_private_key_hex}}"
PDS_CRAWLERS: https://bsky.network
PDS_EMAIL_SMTP_URL: smtps://{{system_email.username}}:{{system_email.password}}@{{system_email.host}}:{{system_email.port}}/
PDS_EMAIL_FROM_ADDRESS: {{system_email.from}}
LOG_ENABLED: true
PDS_BLOBSTORE_DISK_LOCATION: /opt/pds/blocks
# -- DEFAULT VALUES ---
# PDS_DATA_DIRECTORY: /opt/pds
# PDS_BLOB_UPLOAD_LIMIT: 52428800
# PDS_DID_PLC_URL=https://plc.directory
# PDS_BSKY_APP_VIEW_URL=https://api.bsky.app
# PDS_BSKY_APP_VIEW_DID=did:web:api.bsky.app
# PDS_REPORT_SERVICE_URL=https://mod.bsky.app
# PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac
ports: ports:
- "127.0.0.1:{{http_port_api}}:3000" - "127.0.0.1:{{http_port_api}}:3000"
healthcheck: healthcheck:
@ -49,17 +26,14 @@ services:
REACT_APP_API_URL: "http://{{domain_api}}" # API-URL des PDS REACT_APP_API_URL: "http://{{domain_api}}" # API-URL des PDS
REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky" REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky"
REACT_APP_SITE_DESCRIPTION: "Decentral Social " REACT_APP_SITE_DESCRIPTION: "Decentral Social "
restart: {{docker_restart_policy}}
ports: ports:
- "127.0.0.1:{{http_port_web}}:8100" - "127.0.0.1:{{http_port_web}}:8100"
# Start already parallel to pds
#depends_on:
# - None
healthcheck: healthcheck:
test: ["CMD", "sh", "-c", "for pid in $(ls /proc | grep -E '^[0-9]+$'); do if cat /proc/$pid/cmdline 2>/dev/null | grep -q 'bskywebserve'; then exit 0; fi; done; exit 1"] test: ["CMD", "sh", "-c", "for pid in $(ls /proc | grep -E '^[0-9]+$'); do if cat /proc/$pid/cmdline 2>/dev/null | grep -q 'bskywebserve'; then exit 0; fi; done; exit 1"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 3 retries: 3
{% include 'templates/docker/container/networks.yml.j2' %}
{% include 'templates/docker/compose/volumes.yml.j2' %} {% include 'templates/docker/compose/volumes.yml.j2' %}
pds_data: pds_data:

View File

@ -0,0 +1,22 @@
PDS_HOSTNAME="{{domains.bluesky_api}}"
PDS_ADMIN_EMAIL="{{applications.bluesky.administrator_email}}"
PDS_SERVICE_DID="did:web:{{domains.bluesky_api}}"
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
PDS_SERVICE_HANDLE_DOMAINS=".{{primary_domain}}"
PDS_JWT_SECRET="{{applications.bluesky.pds.jwt_secret}}"
PDS_ADMIN_PASSWORD="{{applications.bluesky.pds.admin_password}}"
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="{{applications.bluesky.pds.plc_rotation_key_k256_private_key_hex}}"
PDS_CRAWLERS=https://bsky.network
PDS_EMAIL_SMTP_URL=smtps://{{system_email.username}}:{{system_email.password}}@{{system_email.host}}:{{system_email.port}}/
PDS_EMAIL_FROM_ADDRESS={{system_email.from}}
LOG_ENABLED=true
PDS_BLOBSTORE_DISK_LOCATION=/opt/pds/blocks
# -- DEFAULT VALUES ---
# PDS_DATA_DIRECTORY: /opt/pds
# PDS_BLOB_UPLOAD_LIMIT: 52428800
# PDS_DID_PLC_URL=https://plc.directory
# PDS_BSKY_APP_VIEW_URL=https://api.bsky.app
# PDS_BSKY_APP_VIEW_DID=did:web:api.bsky.app
# PDS_REPORT_SERVICE_URL=https://mod.bsky.app
# PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac

View File

@ -1,8 +1,8 @@
application_id: "bluesky" application_id: "bluesky"
social_app_path: "{{ docker_compose.directories.instance }}/social-app" social_app_path: "{{ docker_compose.directories.services }}/social-app"
# This should be removed when the following issue is closed: # This should be removed when the following issue is closed:
# https://github.com/bluesky-social/pds/issues/52 # https://github.com/bluesky-social/pds/issues/52
pdsadmin_folder_path: "{{ docker_compose.directories.instance }}/pdsadmin" pdsadmin_folder_path: "{{ docker_compose.directories.volumes }}/pdsadmin"
pdsadmin_file_path: "{{pdsadmin_folder_path}}/pdsadmin" pdsadmin_file_path: "{{pdsadmin_folder_path}}/pdsadmin"
pdsadmin_temporary_tar_path: "/tmp/pdsadmin.tar.gz" pdsadmin_temporary_tar_path: "/tmp/pdsadmin.tar.gz"

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,19 +6,7 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "copy docker-compose.yml and env file"
- name: "create {{docker_compose.files.docker_compose}}" include_tasks: copy-docker-compose-and-env.yml
template:
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -9,16 +9,5 @@
loop_control: loop_control:
loop_var: domain loop_var: domain
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -24,19 +24,8 @@
name: central_ldap name: central_ldap
state: present state: present
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup
- name: "create {{docker_compose.directories.env}}phpldapadmin.env" - name: "create {{docker_compose.directories.env}}phpldapadmin.env"
template: template:

View File

@ -15,19 +15,8 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup
- name: add config.toml - name: add config.toml
template: template:

View File

@ -12,19 +12,8 @@
include_role: include_role:
name: nginx-docker-cert-deploy name: nginx-docker-cert-deploy
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup
- name: flush docker service - name: flush docker service
meta: flush_handlers meta: flush_handlers

View File

@ -9,19 +9,8 @@
loop_control: loop_control:
loop_var: domain loop_var: domain
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup
- name: flush docker service - name: flush docker service
meta: flush_handlers meta: flush_handlers

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -18,19 +18,8 @@
dest: "{{docker_compose.directories.volumes}}nginx.conf" dest: "{{docker_compose.directories.volumes}}nginx.conf"
notify: docker compose project setup notify: docker compose project setup
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup
- name: Include OIDC-specific tasks if OIDC client is active - name: Include OIDC-specific tasks if OIDC client is active
include_tasks: oidc_tasks.yml include_tasks: oidc_tasks.yml

View File

@ -50,16 +50,5 @@
state: directory state: directory
mode: 0755 mode: 0755
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -9,16 +9,5 @@
loop_control: loop_control:
loop_var: domain loop_var: domain
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -20,16 +20,5 @@
dest: "{{docker_compose_init}}" dest: "{{docker_compose_init}}"
notify: docker compose project setup notify: docker compose project setup
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -27,17 +27,6 @@
- docker compose project setup - docker compose project setup
- rebuild wordpress container - rebuild wordpress container
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -6,16 +6,5 @@
- name: "include tasks nginx-docker-proxy-domain.yml" - name: "include tasks nginx-docker-proxy-domain.yml"
include_tasks: nginx-docker-proxy-domain.yml include_tasks: nginx-docker-proxy-domain.yml
- name: "create {{docker_compose.files.docker_compose}}" - name: "copy docker-compose.yml and env file"
template: include_tasks: copy-docker-compose-and-env.yml
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup

View File

@ -0,0 +1,13 @@
- name: "create {{docker_compose.files.docker_compose}}"
template:
src: "docker-compose.yml.j2"
dest: "{{docker_compose.files.docker_compose}}"
notify: docker compose project setup
- name: "create {{docker_compose.files.env}}"
template:
src: "env.j2"
dest: "{{docker_compose.files.env}}"
mode: '770'
force: yes
notify: docker compose project setup