This guide deploys the official pre-built Nextcloud Talk container as a standalone High-Performance Backend (HPB). It is intended for an existing, non-AIO Nextcloud installation and does not migrate Nextcloud, its database, files, or reverse proxy to Nextcloud All-in-One.

The container bundles the components needed for a modern Talk backend: the signaling server, Janus media gateway, NATS, and an integrated TURN service. Compared with maintaining the classic multi-container signaling stack yourself, it removes the custom builds and most component-level configuration.

It follows the upstream Nextcloud Talk quick-install documentation and uses the pre-built image maintained in the Nextcloud AIO project.

â„šī¸ WHAT THIS GUIDE INSTALLS

This is the AIO Talk container only, not the complete Nextcloud AIO appliance. Your existing Nextcloud Docker Compose stack stays in place and is configured to use this backend afterwards.

Changelog

DateChange
2026-09-06Initial Version: Added the standalone AIO Talk container tutorial.

1. Prerequisites

This guide assumes that you already have:

  • A working Nextcloud instance with the Talk app enabled.
  • Docker Engine and Docker Compose v2.
  • A Traefik v3 reverse proxy with a shared external Docker network named proxy.
  • A dedicated DNS name for the signaling and TURN service, such as talk.example.com, pointing to the Docker host.
  • A valid TLS certificate for that DNS name.
  • sudo or root access on the Docker host.

The reverse-proxy setup from the following guide is a suitable foundation:

For Docker Compose fundamentals and reverse-proxy behavior, refer to the Docker Compose documentation and the Traefik documentation. If your Nextcloud instance is already behind a proxy, also verify the Nextcloud reverse-proxy settings.

âš ī¸ ONE CONTAINER, ONE NEXTCLOUD BACKEND

The standalone AIO Talk container creates one configured signaling backend from NC_DOMAIN. Do not add multiple unrelated Nextcloud URLs to one container. For two independent Nextcloud instances, deploy two containers with separate endpoints, secrets, and TURN ports as shown in section 8.

1.1. Firewall configuration

The reverse proxy handles HTTPS on ports 80 and 443. The integrated TURN server must be reachable directly on the Talk port over both TCP and UDP. The examples use 3478.

sudo ufw allow 3478/tcp
sudo ufw allow 3478/udp

If your firewall is managed by a cloud provider or hardware router, open and forward the same two ports there as well.

â„šī¸ TURN IS NOT HTTP TRAFFIC

The TURN port bypasses Traefik and its HTTP middleware. Keep the Talk container updated, use a long random TURN secret, and restrict host access with your firewall policy where appropriate.

2. Create the project directory and secrets

Create a dedicated directory for the backend. Keeping the .env file separate prevents secrets from being committed or copied into a public Compose example.

sudo mkdir -p /opt/containers/nextcloud-aio-talk
cd /opt/containers/nextcloud-aio-talk
sudo chmod 700 .

Generate three independent secrets:

openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32

Create .env and replace every placeholder. NC_DOMAIN and TALK_HOST are host names only, without https:// or a path.

sudo tee .env > /dev/null << 'EOF'
# Existing Nextcloud instance that will use this container
NC_DOMAIN=cloud.example.com

# Public DNS name for signaling and TURN
TALK_HOST=talk.example.com

# Keep all three values private and use different random values.
TURN_SECRET=REPLACE_WITH_A_RANDOM_64_HEX_CHARACTER_SECRET
SIGNALING_SECRET=REPLACE_WITH_A_RANDOM_64_HEX_CHARACTER_SECRET
INTERNAL_SECRET=REPLACE_WITH_A_RANDOM_64_HEX_CHARACTER_SECRET
EOF

sudo chmod 600 .env

The secrets have different roles:

SecretPurposeUsed in Nextcloud?
SIGNALING_SECRETAuthenticates the Nextcloud server to the signaling backend.Yes
TURN_SECRETCreates short-lived TURN credentials for Talk clients.Yes
INTERNAL_SECRETProtects internal communication within the backend.No
âš ī¸ DO NOT REUSE PLACEHOLDER VALUES

Never use the placeholder strings from this article. Generate unique random secrets for every Talk container and store the .env file in your password manager or encrypted backup.

3. Create the Docker Compose file

The following Compose file uses Traefik for TLS and WebSocket forwarding. The TURN service is published directly on port 3478, while signaling remains internal and is exposed only through Traefik on port 8081.

sudo tee docker-compose.yml > /dev/null << 'EOF'
services:
  talk:
    image: ghcr.io/nextcloud-releases/aio-talk:latest
    container_name: nextcloud-aio-talk
    init: true
    restart: unless-stopped
    env_file:
      - .env
    environment:
      # Required by the standalone AIO Talk image
      TALK_PORT: "3478"
      TURN_DOMAIN: ${TALK_HOST}
      AIO_LOG_LEVEL: warn
      SKIP_CERT_VERIFY: "false"
    ports:
      - "3478:3478/tcp"
      - "3478:3478/udp"
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.nextcloud-aio-talk.rule=Host(`${TALK_HOST}`)"
      - "traefik.http.routers.nextcloud-aio-talk.entrypoints=websecure"
      - "traefik.http.routers.nextcloud-aio-talk.tls=true"
      - "traefik.http.routers.nextcloud-aio-talk.middlewares=nextcloud-aio-talk-headers@docker,crowdsec-bouncer@docker"
      - "traefik.http.middlewares.nextcloud-aio-talk-headers.headers.customRequestHeaders.X-Forwarded-Proto=https"
      - "traefik.http.services.nextcloud-aio-talk.loadbalancer.server.port=8081"

networks:
  proxy:
    external: true
EOF
â„šī¸ PATH PREFIXES

The preferred layout is one dedicated signaling hostname per container. If a path prefix is unavoidable, add a Traefik StripPrefix middleware and use the same prefix in the High-Performance Backend URL in Nextcloud. A dedicated hostname is simpler to operate and troubleshoot.

4. Start and verify the backend

Pull the image and start the container:

cd /opt/containers/nextcloud-aio-talk
sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps

Verify the public signaling endpoint. The response contains a version string and a welcome message:

curl https://talk.example.com/api/v1/welcome

Check the container logs if the endpoint does not respond:

sudo docker logs --tail 100 nextcloud-aio-talk

Common causes of an unsuccessful start are a DNS record that does not point to the Docker host, a missing TLS certificate, port 3478 already being occupied, or an unreachable NC_DOMAIN from inside the container.

5. Configure Nextcloud Talk

Open Administration settings → Talk in Nextcloud and configure:

SettingValue
High-performance backend URLhttps://talk.example.com
Shared secretThe value of SIGNALING_SECRET
TURN modeturn: only
TURN servertalk.example.com:3478
TURN secretThe value of TURN_SECRET
ProtocolsUDP and TCP

Save the settings and wait for the connection check to finish successfully.

5.1. Configure it using occ (optional)

The same configuration can be added from the Nextcloud container. Replace the placeholders before running the commands.

# Add the signaling endpoint and validate its TLS certificate
php occ talk:signaling:add --verify \
  https://talk.example.com \
  REPLACE_WITH_YOUR_SIGNALING_SECRET

# Add the integrated TURN service
php occ talk:turn:add \
  turn \
  talk.example.com:3478 \
  udp,tcp \
  --secret=REPLACE_WITH_YOUR_TURN_SECRET

List configured endpoints with:

php occ talk:signaling:list
php occ talk:turn:list
âš ī¸ MIGRATION FROM ANOTHER HPB

Run the new backend alongside the old one first. Verify the new URL, configure it in Nextcloud, make a real test call from two different networks, and only then remove the old signaling entry and containers. Keep the old Compose directory until the migration has been verified.

6. Test a real call

The welcome endpoint proves that Traefik can reach the signaling service, but it does not prove that media relay works. Create a Talk room and test a video call:

  1. Join from two separate devices or networks.
  2. Test microphone, camera, screen sharing, and reconnecting after a network change.
  3. Repeat the test from a mobile connection or a restrictive network to confirm TURN fallback.

During a test call, monitor the container:

sudo docker logs -f nextcloud-aio-talk

7. Maintenance and updates

The image is intentionally pre-built, so normal updates do not require rebuilding Signaling, Janus, or NATS from source.

cd /opt/containers/nextcloud-aio-talk
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune

Before updating, back up the project directory, especially .env and docker-compose.yml:

sudo tar -C /opt/containers \
  -czf nextcloud-aio-talk-backup-$(date +%F).tar.gz \
  nextcloud-aio-talk

Review release notes after updates and repeat the signaling endpoint and real-call checks. Do not use a blind docker image prune -a on a production host, as it may remove images used for rollback.

8. Running multiple independent Nextcloud instances

Each standalone AIO Talk container has exactly one NC_DOMAIN and one SIGNALING_SECRET. For two separate Nextcloud instances, use two isolated deployments.

ItemFirst instanceSecond instance
Project directory/opt/containers/nextcloud-aio-talk-one/opt/containers/nextcloud-aio-talk-two
Signaling hostnametalk-one.example.comtalk-two.example.com
Talk / TURN port34783479
Container namenextcloud-aio-talk-onenextcloud-aio-talk-two
NC_DOMAINcloud-one.example.comcloud-two.example.com
SecretsThree unique secretsThree different unique secrets

For the second deployment, copy the project directory, change every identifier shown above, and publish its configured TALK_PORT over TCP and UDP. Each Nextcloud instance then receives only its own signaling URL and its own Signaling and TURN secrets.

âš ī¸ NO SHARED SECRETS ACROSS TENANTS

Do not share SIGNALING_SECRET, TURN_SECRET, or INTERNAL_SECRET between independent Nextcloud instances. Separation makes future rotations, troubleshooting, and decommissioning safer.

9. Recording backend scope

The AIO Talk image provides signaling, media handling, and TURN. It does not include the Talk Recording Backend. Recording is deployed as a separate service and should be planned, secured, and backed up independently.

Continue with Deploying the Nextcloud Talk AIO Recording Backend as a Standalone Container when you need recordings.

10. Troubleshooting

The High-Performance Backend check fails

  • Verify DNS and TLS with curl https://talk.example.com/api/v1/welcome.
  • Confirm that SIGNALING_SECRET matches exactly in .env and in Nextcloud Talk settings.
  • Confirm that NC_DOMAIN is the existing Nextcloud hostname without a scheme or path.
  • Inspect sudo docker logs nextcloud-aio-talk for certificate or connectivity errors.

Calls connect but media does not work

  • Confirm that 3478/tcp and 3478/udp are reachable from the internet.
  • Confirm the TURN hostname, port, secret, and UDP/TCP protocols in Talk settings.
  • Test from an external mobile network, not only from the same LAN.
  • Check provider firewalls and router port forwarding in addition to UFW.

The container cannot contact Nextcloud

  • Ensure the Docker host can resolve and reach https://cloud.example.com.
  • Use a publicly trusted certificate or mount an additional trusted CA certificate when using a private PKI.
  • Do not set SKIP_CERT_VERIFY=true as a permanent workaround.

Conclusion

The standalone AIO Talk image is a practical way to use the maintained, pre-built Talk backend without replacing an existing Nextcloud deployment with full Nextcloud AIO. Keep each Nextcloud instance isolated, protect the secrets, verify TURN with real calls, and retain a tested rollback path during migration.

For the upstream quick-install procedure and current image details, see the official Nextcloud Talk documentation.