Using Docker Compose as Backend for Local Development
Part 1 β SoVisu+ development
This section explains how to use the Docker Compose stack strictly as a backend while running SoVisu+ locally (Next.js dev server) for frontend development.
π― Goal
Run all shared services (Neo4j, message bus, Keycloak, APIs, databases) in Docker, but run SoVisu+ on your host machine. To make this work, you must:
- Map the necessary service ports from containers to the host.
- Use a dedicated profile (e.g.
sovisuplus-db
) to start only SoVisu+ backend services. - Point your local SoVisu+ to these services via env vars and
/etc/hosts
.
π§± Required Hostnames
Add these entries to your /etc/hosts
(if not already done in the main guide):
127.0.0.1 sovisuplus.local
127.0.0.1 keycloak.local
SoVisu+ uses ORCID OAuth, which requires valid hostnames even for sandbox keys.
π Open the Right Ports in Compose
Youβll run SoVisu+ locally, so your host needs to reach the containers. Make sure the following port mappings are enabled.
1) SoVisu+ database (docker/sovisuplus/sovisuplus.yaml
)
Uncomment the ports
section so Postgres is reachable from your host:
sovisuplus.yaml
services:
svp-db:
image: postgres:16
container_name: svp-db
restart: always
environment:
POSTGRES_USER: ${SVP_DB_USER}
POSTGRES_PASSWORD: ${SVP_DB_PASSWORD}
POSTGRES_DB: ${SVP_DB_NAME}
expose:
- 5432
ports:
- 5432:5432
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- svp-network
healthcheck:
test: ['CMD-SHELL', 'pg_isready -d ${SVP_DB_NAME} -U ${SVP_DB_USER}']
interval: 1s
timeout: 5s
retries: 10
command: ["postgres","-c","max_connections=200","-c","superuser_reserved_connections=3"]
profiles:
- sovisuplus
- sovisuplus-db
sovisuplus:
image: crisalidesr/sovisuplus:latest
container_name: sovisuplus
ports:
- 3000:3000
- 3001:3001
environment:
- DB_NAME=${SVP_DB_NAME}
- DB_USER=${SVP_DB_USER}
- DB_PASSWORD=${SVP_DB_PASSWORD}
- DB_HOST=svp-db
- DB_PORT=5432
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- AMQP_HOST=crisalid-bus
- AMQP_PORT=${CRISALID_BUS_AMQP_PORT}
- AMQP_USER=${CRISALID_BUS_USER}
- AMQP_PASSWORD=${CRISALID_BUS_PASSWORD}
- AMQP_QUEUE_NAME=${SVP_AMQP_QUEUE_NAME}
- AMQP_EXCHANGE_NAME=${SVP_AMQP_EXCHANGE_NAME}
- GRAPHQL_ENDPOINT_ENABLED=${GRAPHQL_ENDPOINT_ENABLED}
- GRAPHQL_ENDPOINT_URL=http://apollo:${APOLLO_API_PORT}/graphql
- GRAPHQL_API_KEY_ENABLED=${GRAPHQL_API_KEY_ENABLED}
- KEYCLOAK_CLIENT_ID=sovisuplus
- KEYCLOAK_CLIENT_SECRET=${SOVISUPLUS_KEYCLOAK_CLIENT_SECRET}
- KEYCLOAK_ADDR=${KEYCLOAK_SCHEME}://${KEYCLOAK_HOST}:${KEYCLOAK_PORT}
- KEYCLOAK_REALM=${KEYCLOAK_REALM}
- APP_URL=${SOVISUPLUS_SCHEME}://${SOVISUPLUS_HOST}:${SOVISUPLUS_PORT}
- ORCID_URL=${ORCID_URL}
- ORCID_SCOPES=${ORCID_SCOPES}
- ORCID_CLIENT_ID=${ORCID_CLIENT_ID}
- ORCID_CLIENT_SECRET=${ORCID_CLIENT_SECRET}
- SOVISUPLUS_HOST=${SOVISUPLUS_SCHEME}://${SOVISUPLUS_HOST}:${SOVISUPLUS_PORT}
depends_on:
svp-db:
condition: service_healthy
crisalid-bus:
condition: service_healthy
networks:
- svp-network
- crisalid-front
profiles:
- sovisuplus
networks:
svp-network:
driver: bridge
crisalid-front:
driver: bridge
services:
svp-db:
image: postgres:16
container_name: svp-db
restart: always
environment:
POSTGRES_USER: ${SVP_DB_USER}
POSTGRES_PASSWORD: ${SVP_DB_PASSWORD}
POSTGRES_DB: ${SVP_DB_NAME}
expose:
- 5432
ports:
- 5432:5432
2) Apollo API (docker/apollo/apollo.yaml
)
Ensure the public mapping is present (it typically is already because Apollo graphql GUI is one of the main user interfaces):
apollo.yaml
services:
apollo:
image: crisalidesr/crisalid-apollo:latest
ports:
- ${APOLLO_API_PORT}:4000
depends_on:
neo4j:
condition: service_healthy
environment:
- APP_ENV=DEV
- NEO4J_URI=bolt://neo4j:${NEO4J_BOLT_PORT}
- ENABLE_API_KEYS=${APOLLO_ENABLE_API_KEYS}
networks:
- ikg-network
- crisalid-front
profiles:
- apollo
networks:
ikg-network:
driver: bridge
crisalid-front:
driver: bridge
services:
apollo:
image: crisalidesr/crisalid-apollo:latest
ports:
- ${APOLLO_API_PORT}:4000
Your local SoVisu+ will call
http://localhost:${APOLLO_API_PORT}
(GraphQL endpoint/graphql
).
3) CRISalid Bus / RabbitMQ (docker/crisalid-bus/crisalid-bus.yaml
)
Only the management UI port is exposed by default, but you can uncomment the AMQP port to allow external tools to connect:
crisalid-bus.yaml
services:
crisalid-bus:
image: rabbitmq:3-management
container_name: 'crisalid-bus'
environment:
- RABBITMQ_DEFAULT_USER=${CRISALID_BUS_USER}
- RABBITMQ_DEFAULT_PASS=${CRISALID_BUS_PASSWORD}
- RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=-rabbit load_definitions "${CRISALID_BUS_DEFINITIONS_FILE}"
ports:
- "${CRISALID_BUS_HTTP_PORT}:15672"
- "${CRISALID_BUS_AMQP_PORT}:5672"
expose:
- "${CRISALID_BUS_AMQP_PORT}"
volumes:
- ./rabbitmq-data:/var/lib/rabbitmq
- ./rabbitmq-logs/:/var/log/rabbitmq
- ./definitions.json:${CRISALID_BUS_DEFINITIONS_FILE}:ro
healthcheck:
test: rabbitmq-diagnostics check_port_connectivity
interval: 1s
timeout: 3s
retries: 30
networks:
- crisalid-front
- crisalid-back
profiles:
- crisalid-bus
networks:
crisalid-front:
driver: bridge
crisalid-back:
driver: bridge
services:
crisalid-bus:
image: rabbitmq:3-management
container_name: 'crisalid-bus'
environment:
- RABBITMQ_DEFAULT_USER=${CRISALID_BUS_USER}
- RABBITMQ_DEFAULT_PASS=${CRISALID_BUS_PASSWORD}
- RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=-rabbit load_definitions "${CRISALID_BUS_DEFINITIONS_FILE}"
ports:
- "${CRISALID_BUS_HTTP_PORT}:15672"
- "${CRISALID_BUS_AMQP_PORT}:5672"
expose:
- "${CRISALID_BUS_AMQP_PORT}"
π§© Use the Backend-Only Profile
Replace the sovisuplus
profile with sovisuplus-db
, which starts the DB and related services but not the SoVisu+ container itself.
Example command:
docker compose \
--profile cdb \
--profile neo4j \
--profile apollo \
--profile crisalid-bus \
--profile harvester \
--profile ikg \
--profile keycloak \
--profile sovisuplus-db \
--remove-orphans up
βΆοΈ Run SoVisu+ Locally
Start your Next.js app on the host as usual (e.g., in the SoVisu+ repo):
npm run dev # for the main web gui
npm run dev:listener # for the backend listener
Make sure your local env points to the Docker services. Typical variables (names vary by project):
NEXT_PUBLIC_SUPPORTED_LOCALES="fr,en"
DATABASE_URL="postgresql://sovisuplus:sovisuplus_password@localhost:5432/sovisuplus?schema=public"
KEYCLOAK_CLIENT_ID="sovisuplus"
KEYCLOAK_CLIENT_SECRET="use-the-same-secret-as-in-docker-compose"
KEYCLOAK_ISSUER="http://keycloak.local:8080/realms/crisalid-inst"
NEXTAUTH_URL="http://sovisuplus.local:3000/api/auth"
NEXTAUTH_SECRET="use-a-secure-random-secret"
AMQP_USER="crisalid_bus_user"
AMQP_PASSWORD="use-the-same-password-as-in-docker-compose"
AMQP_HOST="localhost"
AMQP_PORT="5672"
AMQP_QUEUE_NAME="sovisuplus"
AMQP_EXCHANGE_NAME="graph"
GRAPHQL_ENDPOINT_ENABLED="true"
GRAPHQL_ENDPOINT_URL="http://localhost:4000/graphql"
GRAPHQL_API_KEY_ENABLED="false"
GRAPHQL_API_KEY="not-needed-in-dev"
PERSPECTIVES_ROLES_FILTER="author"
PUBLICATION_LIST_ROLES_FILTER="author"
ORCID_URL="https://sandbox.orcid.org"
SOVISUPLUS_HOST="http://sovisuplus.local:3000"
ORCID_SCOPES="/person/update"
ORCID_CLIENT_ID="use-the-same-client-id--provided-by-orcid-as-in-docker-compose"
ORCID_CLIENT_SECRET="use-the-same-client-secret-provided-by-orcid-as-in-docker-compose"
Visit SoVisu+ at:
http://sovisuplus.local:3000