services: # Dependencies postgres: image: postgres:15.5 volumes: - postgres-data:/var/lib/postgresql/data environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: firezone_dev healthcheck: test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] start_period: 20s interval: 30s retries: 5 timeout: 5s ports: - 5432:5432/tcp networks: - app vault: image: vault:1.13.3 environment: VAULT_ADDR: "http://127.0.0.1:8200" VAULT_DEV_ROOT_TOKEN_ID: "firezone" VAULT_LOG_LEVEL: "debug" ports: - 8200:8200/tcp cap_add: - IPC_LOCK networks: - app healthcheck: test: [ "CMD", "wget", "--spider", "--proxy", "off", "http://127.0.0.1:8200/v1/sys/health?standbyok=true", ] interval: 10s timeout: 3s retries: 10 start_period: 5s # Firezone Components web: build: context: elixir cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/web:main args: APPLICATION_NAME: web image: ${WEB_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/web}:${WEB_TAG:-main} hostname: web.cluster.local ports: - 8080:8080/tcp environment: # Web Server EXTERNAL_URL: http://localhost:8080/ PHOENIX_HTTP_WEB_PORT: "8080" PHOENIX_SECURE_COOKIES: "false" # Erlang ERLANG_DISTRIBUTION_PORT: 9000 ERLANG_CLUSTER_ADAPTER: "Elixir.Cluster.Strategy.Epmd" ERLANG_CLUSTER_ADAPTER_CONFIG: '{"hosts":["api@api.cluster.local","web@web.cluster.local","domain@web.cluster.local"]}' RELEASE_COOKIE: "NksuBhJFBhjHD1uUa9mDOHV" RELEASE_HOSTNAME: "web.cluster.local" RELEASE_NAME: "web" # Database DATABASE_HOST: postgres DATABASE_PORT: 5432 DATABASE_NAME: firezone_dev DATABASE_USER: postgres DATABASE_PASSWORD: postgres # Auth AUTH_PROVIDER_ADAPTERS: "email,openid_connect,userpass,token,google_workspace,microsoft_entra,okta,jumpcloud" # Secrets TOKENS_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" TOKENS_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" SECRET_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" LIVE_VIEW_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_ENCRYPTION_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" # Debugging LOG_LEVEL: "debug" # Emails OUTBOUND_EMAIL_FROM: "public-noreply@firez.one" OUTBOUND_EMAIL_ADAPTER: "Elixir.Swoosh.Adapters.Postmark" ## Warning: The token is for the blackhole Postmark server created in a separate isolated account, ## that WILL NOT send any actual emails, but you can see and debug them in the Postmark dashboard. OUTBOUND_EMAIL_ADAPTER_OPTS: '{"api_key":"7da7d1cd-111c-44a7-b5ac-4027b9d230e5"}' # Seeds STATIC_SEEDS: "true" # Feature flags FLOW_ACTIVITIES_ENABLED: "true" FEATURE_POLICY_CONDITIONS_ENABLED: "true" MULTI_SITE_RESOURCES_ENABLED: "true" SELF_HOSTED_RELAYS_ENABLED: "true" IDP_SYNC_ENABLED: "true" REST_API_ENABLED: "true" healthcheck: test: ["CMD-SHELL", "curl -f localhost:8080/healthz"] start_period: 10s interval: 30s retries: 5 timeout: 5s depends_on: vault: condition: "service_healthy" postgres: condition: "service_healthy" networks: - app api: build: context: elixir cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/api:main args: APPLICATION_NAME: api image: ${API_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/api}:${API_TAG:-main} hostname: api.cluster.local ports: - 8081:8081/tcp environment: # Web Server EXTERNAL_URL: http://localhost:8081/ PHOENIX_HTTP_API_PORT: "8081" PHOENIX_SECURE_COOKIES: "false" # Erlang ERLANG_DISTRIBUTION_PORT: 9000 ERLANG_CLUSTER_ADAPTER: "Elixir.Cluster.Strategy.Epmd" ERLANG_CLUSTER_ADAPTER_CONFIG: '{"hosts":["api@api.cluster.local","web@web.cluster.local","domain@web.cluster.local"]}' RELEASE_COOKIE: "NksuBhJFBhjHD1uUa9mDOHV" RELEASE_HOSTNAME: "api.cluster.local" RELEASE_NAME: "api" # Database DATABASE_HOST: postgres DATABASE_PORT: 5432 DATABASE_NAME: firezone_dev DATABASE_USER: postgres DATABASE_PASSWORD: postgres # Auth AUTH_PROVIDER_ADAPTERS: "email,openid_connect,userpass,token,google_workspace,microsoft_entra,okta,jumpcloud" # Secrets TOKENS_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" TOKENS_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" SECRET_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" LIVE_VIEW_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_ENCRYPTION_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" # Debugging LOG_LEVEL: "debug" # Emails OUTBOUND_EMAIL_FROM: "public-noreply@firez.one" OUTBOUND_EMAIL_ADAPTER: "Elixir.Swoosh.Adapters.Postmark" ## Warning: The token is for the blackhole Postmark server created in a separate isolated account, ## that WILL NOT send any actual emails, but you can see and debug them in the Postmark dashboard. OUTBOUND_EMAIL_ADAPTER_OPTS: '{"api_key":"7da7d1cd-111c-44a7-b5ac-4027b9d230e5"}' # Seeds STATIC_SEEDS: "true" # Feature flags FLOW_ACTIVITIES_ENABLED: "true" FEATURE_POLICY_CONDITIONS_ENABLED: "true" MULTI_SITE_RESOURCES_ENABLED: "true" SELF_HOSTED_RELAYS_ENABLED: "true" IDP_SYNC_ENABLED: "true" REST_API_ENABLED: "true" depends_on: vault: condition: "service_healthy" postgres: condition: "service_healthy" healthcheck: test: ["CMD-SHELL", "curl -f localhost:8081/healthz"] start_period: 10s interval: 30s retries: 5 timeout: 5s networks: - app domain: build: context: elixir cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/domain:main args: APPLICATION_NAME: domain image: ${API_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/domain}:${API_TAG:-main} hostname: domain.cluster.local environment: # Erlang ERLANG_DISTRIBUTION_PORT: 9000 ERLANG_CLUSTER_ADAPTER: "Elixir.Cluster.Strategy.Epmd" ERLANG_CLUSTER_ADAPTER_CONFIG: '{"hosts":["api@api.cluster.local","web@web.cluster.local","domain@domain.cluster.local"]}' RELEASE_COOKIE: "NksuBhJFBhjHD1uUa9mDOHV" RELEASE_HOSTNAME: "domain.cluster.local" RELEASE_NAME: "domain" # Database DATABASE_HOST: postgres DATABASE_PORT: 5432 DATABASE_NAME: firezone_dev DATABASE_USER: postgres DATABASE_PASSWORD: postgres # Auth AUTH_PROVIDER_ADAPTERS: "email,openid_connect,userpass,token,google_workspace,microsoft_entra,okta,jumpcloud" # Secrets TOKENS_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" TOKENS_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" SECRET_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" LIVE_VIEW_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_ENCRYPTION_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" # Debugging LOG_LEVEL: "debug" # Emails OUTBOUND_EMAIL_FROM: "public-noreply@firez.one" OUTBOUND_EMAIL_ADAPTER: "Elixir.Swoosh.Adapters.Postmark" ## Warning: The token is for the blackhole Postmark server created in a separate isolated account, ## that WILL NOT send any actual emails, but you can see and debug them in the Postmark dashboard. OUTBOUND_EMAIL_ADAPTER_OPTS: '{"api_key":"7da7d1cd-111c-44a7-b5ac-4027b9d230e5"}' # Seeds STATIC_SEEDS: "true" # Feature flags FLOW_ACTIVITIES_ENABLED: "true" FEATURE_POLICY_CONDITIONS_ENABLED: "true" MULTI_SITE_RESOURCES_ENABLED: "true" SELF_HOSTED_RELAYS_ENABLED: "true" IDP_SYNC_ENABLED: "true" REST_API_ENABLED: "true" healthcheck: test: ["CMD-SHELL", "curl -f localhost:4000/healthz"] start_period: 10s interval: 30s retries: 5 timeout: 5s depends_on: vault: condition: "service_healthy" postgres: condition: "service_healthy" networks: - app # This is a service container which allows to run mix tasks for local development # without having to install Elixir and Erlang on the host machine. elixir: build: context: elixir target: compiler cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/elixir:main args: APPLICATION_NAME: api image: ${ELIXIR_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/elixir}:${ELIXIR_TAG:-main} hostname: elixir environment: # Web Server EXTERNAL_URL: http://localhost:8081/ # Erlang ERLANG_DISTRIBUTION_PORT: 9000 RELEASE_COOKIE: "NksuBhJFBhjHD1uUa9mDOHV" RELEASE_HOSTNAME: "mix.cluster.local" RELEASE_NAME: "mix" # Database DATABASE_HOST: postgres DATABASE_PORT: 5432 DATABASE_NAME: firezone_dev DATABASE_USER: postgres DATABASE_PASSWORD: postgres # Auth AUTH_PROVIDER_ADAPTERS: "email,openid_connect,userpass,token,google_workspace,microsoft_entra,okta,jumpcloud" # Secrets TOKENS_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" TOKENS_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" SECRET_KEY_BASE: "5OVYJ83AcoQcPmdKNksuBhJFBhjHD1uUa9mDOHV/6EIdBQ6pXksIhkVeWIzFk5S2" LIVE_VIEW_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_SIGNING_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" COOKIE_ENCRYPTION_SALT: "t01wa0K4lUd7mKa0HAtZdE+jFOPDDej2" # Higher log level not to make seeds output too verbose LOG_LEVEL: "info" # Emails OUTBOUND_EMAIL_FROM: "public-noreply@firez.one" OUTBOUND_EMAIL_ADAPTER: "Elixir.Swoosh.Adapters.Postmark" ## Warning: The token is for the blackhole Postmark server created in a separate isolated account, ## that WILL NOT send any actual emails, but you can see and debug them in the Postmark dashboard. OUTBOUND_EMAIL_ADAPTER_OPTS: '{"api_key":"7da7d1cd-111c-44a7-b5ac-4027b9d230e5"}' # Mix env should be set to prod to use secrets declared above, # otherwise seeds will generate invalid tokens MIX_ENV: "prod" # Seeds STATIC_SEEDS: "true" # Feature flags FLOW_ACTIVITIES_ENABLED: "true" FEATURE_POLICY_CONDITIONS_ENABLED: "true" MULTI_SITE_RESOURCES_ENABLED: "true" SELF_HOSTED_RELAYS_ENABLED: "true" IDP_SYNC_ENABLED: "true" REST_API_ENABLED: "true" depends_on: postgres: condition: "service_healthy" networks: - app client: environment: FIREZONE_DNS_CONTROL: "${FIREZONE_DNS_CONTROL:-etc-resolv-conf}" FIREZONE_TOKEN: "n.SFMyNTY.g2gDaANtAAAAJGM4OWJjYzhjLTkzOTItNGRhZS1hNDBkLTg4OGFlZjZkMjhlMG0AAAAkN2RhN2QxY2QtMTExYy00NGE3LWI1YWMtNDAyN2I5ZDIzMGU1bQAAACtBaUl5XzZwQmstV0xlUkFQenprQ0ZYTnFJWktXQnMyRGR3XzJ2Z0lRdkZnbgYAGUmu74wBYgABUYA.UN3vSLLcAMkHeEh5VHumPOutkuue8JA6wlxM9JxJEPE" RUST_LOG: firezone_linux_client=trace,wire=trace,connlib_client_shared=trace,firezone_tunnel=trace,connlib_shared=trace,boringtun=debug,snownet=debug,str0m=debug,info FIREZONE_API_URL: ws://api:8081 init: true build: target: dev context: rust dockerfile: Dockerfile cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/client:main args: PACKAGE: firezone-headless-client image: ${CLIENT_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/dev/client}:${CLIENT_TAG:-main} cap_add: - NET_ADMIN sysctls: - net.ipv6.conf.all.disable_ipv6=0 devices: - "/dev/net/tun:/dev/net/tun" depends_on: api: condition: "service_healthy" networks: app: ipv4_address: 172.28.0.100 gateway: healthcheck: test: ["CMD-SHELL", "ip link | grep tun-firezone"] environment: FIREZONE_TOKEN: ".SFMyNTY.g2gDaANtAAAAJGM4OWJjYzhjLTkzOTItNGRhZS1hNDBkLTg4OGFlZjZkMjhlMG0AAAAkMjI3NDU2MGItZTk3Yi00NWU0LThiMzQtNjc5Yzc2MTdlOThkbQAAADhPMDJMN1VTMkozVklOT01QUjlKNklMODhRSVFQNlVPOEFRVk82VTVJUEwwVkpDMjJKR0gwPT09PW4GAF3gLBONAWIAAVGA.DCT0Qv80qzF5OQ6CccLKXPLgzC3Rzx5DqzDAh9mWAww" RUST_LOG: phoenix_channel=trace,firezone_gateway=trace,wire=trace,connlib_gateway_shared=trace,firezone_tunnel=trace,connlib_shared=trace,phoenix_channel=debug,boringtun=debug,snownet=debug,str0m=debug,info FIREZONE_ENABLE_MASQUERADE: 1 FIREZONE_API_URL: ws://api:8081 FIREZONE_ID: 4694E56C-7643-4A15-9DF3-638E5B05F570 build: target: dev context: rust dockerfile: Dockerfile cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/gateway:main args: PACKAGE: firezone-gateway image: ${GATEWAY_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/dev/gateway}:${GATEWAY_TAG:-main} cap_add: - NET_ADMIN sysctls: - net.ipv4.ip_forward=1 - net.ipv4.conf.all.src_valid_mark=1 - net.ipv6.conf.all.disable_ipv6=0 - net.ipv6.conf.all.forwarding=1 - net.ipv6.conf.default.forwarding=1 devices: - "/dev/net/tun:/dev/net/tun" depends_on: api: condition: "service_healthy" networks: app: ipv4_address: 172.28.0.105 dns_resources: resources: httpbin: image: kennethreitz/httpbin healthcheck: test: ["CMD-SHELL", "ps -C gunicorn"] networks: resources: ipv4_address: 172.20.0.100 download.httpbin: # Named after `httpbin` because that is how DNS resources are configured for the test setup. build: target: dev context: rust dockerfile: Dockerfile cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/http-test-server:main args: PACKAGE: http-test-server image: ${HTTP_TEST_SERVER_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/dev/http-test-server}:${HTTP_TEST_SERVER_TAG:-main} environment: PORT: 80 networks: dns_resources: ipv4_address: 172.21.0.101 dns.httpbin: image: kennethreitz/httpbin healthcheck: test: ["CMD-SHELL", "ps -C gunicorn"] networks: dns_resources: ipv4_address: 172.21.0.100 iperf3: image: mlabbe/iperf3 healthcheck: test: ["CMD-SHELL", "(cat /proc/net/tcp | grep 5201) && (cat /proc/net/udp | grep 5201)"] command: -s -V networks: resources: ipv4_address: 172.20.0.110 relay-1: environment: PUBLIC_IP4_ADDR: ${RELAY_1_PUBLIC_IP4_ADDR:-172.28.0.101} # PUBLIC_IP6_ADDR: fcff:3990:3990::101 LOWEST_PORT: 55555 HIGHEST_PORT: 55666 # Token for self-hosted Relay # FIREZONE_TOKEN: ".SFMyNTY.g2gDaANtAAAAJGM4OWJjYzhjLTkzOTItNGRhZS1hNDBkLTg4OGFlZjZkMjhlMG0AAAAkNTQ5YzQxMDctMTQ5Mi00ZjhmLWE0ZWMtYTlkMmE2NmQ4YWE5bQAAADhQVTVBSVRFMU84VkRWTk1ITU9BQzc3RElLTU9HVERJQTY3MlM2RzFBQjAyT1MzNEg1TUUwPT09PW4GAEngLBONAWIAAVGA.E-f2MFdGMX7JTL2jwoHBdWcUd2G3UNz2JRZLbQrlf0k" # Token for global Relay FIREZONE_TOKEN: ".SFMyNTY.g2gDaAN3A25pbG0AAAAkZTgyZmNkYzEtMDU3YS00MDE1LWI5MGItM2IxOGYwZjI4MDUzbQAAADhDMTROR0E4N0VKUlIwM0c0UVBSMDdBOUM2Rzc4NFRTU1RIU0Y0VEk1VDBHRDhENkwwVlJHPT09PW4GADXgLBONAWIAAVGA.dShU17FgnvO2GLcTSnBBTDoqQ2tScuG7qjiyKhhlq8s" RUST_LOG: "debug" RUST_BACKTRACE: 1 FIREZONE_API_URL: ws://api:8081 build: target: dev context: rust dockerfile: Dockerfile cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/relay:main args: PACKAGE: firezone-relay image: ${RELAY_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/dev/relay}:${RELAY_TAG:-main} healthcheck: test: ["CMD-SHELL", "lsof -i UDP | grep firezone-relay"] start_period: 10s interval: 30s retries: 5 timeout: 5s depends_on: api: condition: "service_healthy" ports: # NOTE: Only 111 ports are used for local dev / testing because Docker Desktop # allocates a userland proxy process for each forwarded port X_X. # # Large ranges here will bring your machine to its knees. - "55555-55666:55555-55666/udp" - 3478:3478/udp networks: app: ipv4_address: ${RELAY_1_PUBLIC_IP4_ADDR:-172.28.0.101} relay-2: environment: PUBLIC_IP4_ADDR: ${RELAY_2_PUBLIC_IP4_ADDR:-172.28.0.201} # PUBLIC_IP6_ADDR: fcff:3990:3990::101 # Token for self-hosted Relay # FIREZONE_TOKEN: ".SFMyNTY.g2gDaANtAAAAJGM4OWJjYzhjLTkzOTItNGRhZS1hNDBkLTg4OGFlZjZkMjhlMG0AAAAkNTQ5YzQxMDctMTQ5Mi00ZjhmLWE0ZWMtYTlkMmE2NmQ4YWE5bQAAADhQVTVBSVRFMU84VkRWTk1ITU9BQzc3RElLTU9HVERJQTY3MlM2RzFBQjAyT1MzNEg1TUUwPT09PW4GAEngLBONAWIAAVGA.E-f2MFdGMX7JTL2jwoHBdWcUd2G3UNz2JRZLbQrlf0k" # Token for global Relay FIREZONE_TOKEN: ".SFMyNTY.g2gDaAN3A25pbG0AAAAkZTgyZmNkYzEtMDU3YS00MDE1LWI5MGItM2IxOGYwZjI4MDUzbQAAADhDMTROR0E4N0VKUlIwM0c0UVBSMDdBOUM2Rzc4NFRTU1RIU0Y0VEk1VDBHRDhENkwwVlJHPT09PW4GADXgLBONAWIAAVGA.dShU17FgnvO2GLcTSnBBTDoqQ2tScuG7qjiyKhhlq8s" RUST_LOG: "debug" RUST_BACKTRACE: 1 FIREZONE_API_URL: ws://api:8081 build: target: dev context: rust dockerfile: Dockerfile cache_from: - type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/relay:main args: PACKAGE: firezone-relay image: ${RELAY_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/dev/relay}:${RELAY_TAG:-main} healthcheck: test: ["CMD-SHELL", "lsof -i UDP | grep firezone-relay"] start_period: 10s interval: 30s retries: 5 timeout: 5s depends_on: api: condition: "service_healthy" networks: app: ipv4_address: ${RELAY_2_PUBLIC_IP4_ADDR:-172.28.0.201} # IPv6 is currently causing flakiness with GH actions and on our testbed. # Disabling until there's more time to debug. networks: # Using a separate subnet here so that the CIDR resource for 172.20.0.0 won't catch DNS resources dns_resources: ipam: config: - subnet: 172.21.0.0/24 resources: # enable_ipv6: true ipam: config: - subnet: 172.20.0.0/24 # - subnet: fc00:ff:1::/48 app: # enable_ipv6: true ipam: config: - subnet: 172.28.0.0/24 # Currently not working on testbed # - subnet: fc00:ff:2::/48 volumes: postgres-data: elixir-build-cache: assets-build-cache: