Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 268 additions & 0 deletions docker-compose-legacy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
version: '3.4'

x-portainer-image: &portainer-image
portainer/portainer-ce
x-traefik-image: &traefik-image
traefik:v2.8
x-cassandra-oai: &cassandra-oai-image
cassandra:4.1
x-cassandra-backup-image: &cassandra-backup-image
docker.dev.fiz-karlsruhe.de/cassandra-backup:5.2
x-elasticsearch-oai-image: &elasticsearch-oai-image
docker.elastic.co/elasticsearch/elasticsearch:7.17.13
x-oai-backend-image: &oai-backend-image
docker.dev.fiz-karlsruhe.de/oai-backend:1.5.8
x-oai-provider-image: &oai-provider-image
docker.dev.fiz-karlsruhe.de/oai-provider:1.5.3
x-python-zbmathrest2oai-image: &python-zbmathrest2oai-image
ghcr.io/mardi4nfdi/python-zbmathrest2oai:main
x-swmath2swh-image: &swmath2swh-image
ghcr.io/mardi4nfdi/swmath2swh:latest
x-uptime-kuma-image: &uptime-kuma-image
louislam/uptime-kuma:2

services:
traefik:
restart: always
image: *traefik-image
container_name: reverse-proxy
ports:
- 443:443 # HTTPS port
- ${TRAEFIK_HTTP_PORT}:80 # HTTP port
volumes:
- /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
- ./traefik/conf/:/traefik-conf/:ro
- traefik-letsencrypt:/letsencrypt # Persistent file for ACME Setup (Certificate Store)
- ./traefik-log:/data/log # Persistent file for logging (currently not used)
networks:
- default
labels:
- traefik.http.routers.dashboard.rule=Host(`traefik.${WIKIBASE_HOST}`)
- traefik.http.routers.dashboard.entrypoints=websecure
- traefik.http.routers.dashboard.tls.certResolver=le
- traefik.http.routers.dashboard.service=api@internal
- traefik.http.routers.dashboard.middlewares=auth
- traefik.http.middlewares.auth.basicauth.users=mardi:$$2y$$05$$Ubl1B.74bDJkpGHXZ6Y4Xuq8lSx88bi51bmE85/VYf1nQizfKKuH.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hardcoded basic auth credentials in version control.

The bcrypt-hashed password is committed to the repository. While the hash is not reversible, it's better practice to reference credentials via environment variables or external secrets management, especially for production configurations.

Suggested approach
-      - traefik.http.middlewares.auth.basicauth.users=mardi:$$2y$$05$$Ubl1B.74bDJkpGHXZ6Y4Xuq8lSx88bi51bmE85/VYf1nQizfKKuH.
+      - traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_BASIC_AUTH_USERS}

Then define TRAEFIK_BASIC_AUTH_USERS in your .env file (which should be gitignored).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- traefik.http.middlewares.auth.basicauth.users=mardi:$$2y$$05$$Ubl1B.74bDJkpGHXZ6Y4Xuq8lSx88bi51bmE85/VYf1nQizfKKuH.
- traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_BASIC_AUTH_USERS}
🤖 Prompt for AI Agents
In @docker-compose-legacy.yml at line 48, Replace the hardcoded traefik
middleware credential value in the docker-compose entry
(traefik.http.middlewares.auth.basicauth.users) with an environment variable
reference and load that variable from .env (e.g., TRAEFIK_BASIC_AUTH_USERS);
update the docker-compose service to use "${TRAEFIK_BASIC_AUTH_USERS}" for
traefik.http.middlewares.auth.basicauth.users and add instructions to set
TRAEFIK_BASIC_AUTH_USERS in the gitignored .env (or secret store) instead of
committing the bcrypt hash.

environment:
- WIKIBASE_HOST=${WIKIBASE_HOST}

portainer:
container_name: mardi-portainer
image: *portainer-image
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock # needs access to docker process
- portainer-data:/data # volume to save settings of portainer
labels:
- traefik.http.routers.service-portainer.rule=Host(`portainer.${WIKIBASE_HOST}`)
- traefik.http.routers.service-portainer.entrypoints=websecure
- traefik.http.routers.service-portainer.tls.certResolver=le
- traefik.http.services.portainer-docker.loadbalancer.server.port=9000

uptime-kuma:
image: *uptime-kuma-image
container_name: uptime-kuma
volumes:
- uptime-kuma:/app/data
restart: always
labels:
- traefik.http.routers.uptime.rule=Host(`uptime.${WIKIBASE_HOST}`)
- traefik.http.routers.uptime.entrypoints=websecure
- traefik.http.routers.uptime.tls.certResolver=le

cassandra-oai:
hostname: cassandra-oai
image: *cassandra-oai-image
environment:
LOG4J_FORMAT_MSG_NO_LOOKUPS: "true"
volumes:
- cassandra-data:/var/lib/cassandra/
- ./oaipmh/cassandra.yaml:/etc/cassandra/cassandra.yaml
- ./oaipmh/cassandra-env.sh:/etc/cassandra/cassandra-env.sh
- ./oaipmh/jmxremote.access:/opt/java/openjdk/lib/management/jmxremote.access
- ./oaipmh/jmxremote.password:/etc/cassandra/jmxremote.password
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the docker-compose-legacy.yml file around lines 83-84
head -n 90 docker-compose-legacy.yml | tail -n 20

Repository: MaRDI4NFDI/portal-compose

Length of output: 773


🏁 Script executed:

# Search for the jmxremote.password file in the repository
fd -t f 'jmxremote.password' -x stat -c '%a %n' {} \; 2>/dev/null || echo "File not found in repository"

Repository: MaRDI4NFDI/portal-compose

Length of output: 97


🏁 Script executed:

# Also check if the oaipmh directory and related files exist
ls -la oaipmh/ 2>/dev/null || echo "oaipmh directory not found"

Repository: MaRDI4NFDI/portal-compose

Length of output: 1039


Fix JMX credential file permissions: change from 644 to 600.

The jmxremote.password file at ./oaipmh/jmxremote.password currently has permissions 644 (readable by group and others), but should be restricted to 600 (readable/writable by owner only) to protect the sensitive JMX credentials. Run chmod 600 ./oaipmh/jmxremote.password to remediate.

🤖 Prompt for AI Agents
In @docker-compose-legacy.yml around lines 83 - 84, The jmxremote.password file
mounted in the docker-compose bind mount (./oaipmh/jmxremote.password) currently
has overly permissive mode 644; change its permissions to 600 to restrict access
by running chmod 600 ./oaipmh/jmxremote.password on the host so the JMX
credential file used by the jmxremote.password bind mount is readable/writable
only by the owner.


cassandra-oai-setup:
hostname: cassandra-oai-setup
image: *cassandra-oai-image
depends_on:
- cassandra-oai
command: ["/wait-for-it.sh","cassandra-oai:9042","--", "sh", "/init-fizoai-database.sh"]
volumes:
- ./oaipmh/init-fizoai-database.sh:/init-fizoai-database.sh:ro
- ./oaipmh/wait-for-it.sh:/wait-for-it.sh:ro

cassandra-backup:
hostname: cassandra-backup
image: *cassandra-backup-image
environment:
JAVA_OPTS: "-Dlog4j2.formatMsgNoLookups=true"
LOG4J_FORMAT_MSG_NO_LOOKUPS: "true"
env_file:
- ./oaipmh/.cassandra_dump_env
volumes:
- backup-logs:/logs
- cassandra-data:/source_data
- ./cassandra-backup:/backup
depends_on:
- cassandra-oai

elasticsearch-oai:
hostname: elasticsearch-oai
image: *elasticsearch-oai-image
environment:
# - bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Dlog4j2.formatMsgNoLookups=true -Xms2g -Xmx2g"
- "LOG4J_FORMAT_MSG_NO_LOOKUPS=true"
- discovery.type=single-node
- xpack.security.enabled=false
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es-logs:/usr/share/elasticsearch/logs
- es-data:/usr/share/elasticsearch/data

oai-backend:
hostname: oai-backend
image: *oai-backend-image
environment:
- "LOG4J_FORMAT_MSG_NO_LOOKUPS=true"
- "CATALINA_OPTS=-Dlog4j2.formatMsgNoLookups=true -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
depends_on:
- cassandra-oai
- elasticsearch-oai
links:
- "cassandra-oai"
- "elasticsearch-oai"
volumes:
- ./oaipmh/fiz-oai-backend.properties:/usr/local/tomcat/conf/fiz-oai-backend.properties:ro
- backend-logs:/usr/local/tomcat/logs
labels:
- traefik.http.routers.service-oai-backend.rule=Host(`oai-input.${WIKIBASE_HOST}`)
- traefik.http.routers.service-oai-backend.entrypoints=websecure
- traefik.http.routers.service-oai-backend.tls.certResolver=le
- traefik.http.middlewares.oai-auth.basicauth.users=swmath:$$2y$$05$$w37F7z0zZb0ytCvCrxRohOSlcl3lSx9OV9mGTOWOBuMsRRht7LLaO
- traefik.http.routers.service-oai-backend.middlewares=oai-auth

oai-provider:
hostname: oai-provider
image: *oai-provider-image
environment:
- "LOG4J_FORMAT_MSG_NO_LOOKUPS=true"
- "CATALINA_OPTS=-Dlog4j2.formatMsgNoLookups=true -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
depends_on:
- oai-backend
links:
- "oai-backend"
volumes:
- ./oaipmh/oaicat.properties:/usr/local/tomcat/conf/oaicat.properties:ro
- provider-logs:/usr/local/tomcat/logs
labels:
- traefik.http.routers.oai-provider.rule=Host(`oai.${WIKIBASE_HOST}`)
- traefik.http.routers.oai-provider.entrypoints=websecure
- traefik.http.routers.oai-provider.tls.certResolver=le

oai-importer:
hostname: oai-importer
image: *python-zbmathrest2oai-image
environment:
# start over on each run
- OAI_STATE_PATH=/tmp/state.json
depends_on:
- oai-backend
restart: always

swmath-swh:
hostname: swmath-swh
image: *swmath2swh-image
environment:
# start over on each run
- OAI_STATE_PATH=/var/lib/swmath/state.json
- SWH_API_TOKEN
- SWMATH_USER_DEPOSIT_PRODUCTION
- SWMATH_PWD_DEPOSIT_PRODUCTION
depends_on:
- oai-backend
restart: always
volumes:
- swmath-state:/var/lib/swmath/

# see https://github.com/ipfs/kubo/blob/master/docker-compose.yaml
ipfs:
image: ipfs/kubo
restart: unless-stopped
ports:
- 4001:4001/tcp
- 4001:4001/udp
volumes:
- ipfs-staging:/export
- ipfs-data:/data/ipfs
environment:
- IPFS_PROFILE=server
labels:
- com.centurylinklabs.watchtower.enable=true

# public gateway
- traefik.http.services.kubo-service.loadbalancer.server.port=8080
- traefik.http.routers.kubo-docker.service=kubo-service
- traefik.http.routers.kubo-docker.rule=Host(`ipfs.${WIKIBASE_HOST}`)
- traefik.http.routers.kubo-docker.entrypoints=websecure
- traefik.http.routers.kubo-docker.tls.certResolver=le

#internal management interface
- traefik.http.services.kubo-rpc-service.loadbalancer.server.port=5001
- traefik.http.routers.kubo-rpc-docker.service=kubo-rpc-service
- traefik.http.routers.kubo-rpc-docker.middlewares=auth
- traefik.http.routers.kubo-rpc-docker.rule=Host(`ipfs-admin.${WIKIBASE_HOST}`)
- traefik.http.routers.kubo-rpc-docker.entrypoints=websecure
- traefik.http.routers.kubo-rpc-docker.tls.certResolver=le

mscexplainer:
image: ghcr.io/gipplab/automscexplainer:latest
restart: always
labels:
- com.centurylinklabs.watchtower.enable=true
- traefik.http.routers.mscexplainer.rule=Host(`mscexplainer.${WIKIBASE_HOST}`)
- traefik.http.routers.mscexplainer.entrypoints=websecure
- traefik.http.routers.mscexplainer.tls.certResolver=le

mscbackend:
image: aggipp/automscbackend
restart: always
labels:
- com.centurylinklabs.watchtower.enable=true
- traefik.http.routers.mscbackend.rule=Host(`mscbackend.${WIKIBASE_HOST}`)
- traefik.http.routers.mscbackend.entrypoints=websecure
- traefik.http.routers.mscbackend.tls.certResolver=le

msceval:
image: aggipp/automsceval
restart: always
labels:
- com.centurylinklabs.watchtower.enable=true
- traefik.http.routers.msceval.rule=Host(`msceval.${WIKIBASE_HOST}`)
- traefik.http.routers.msceval.entrypoints=websecure
- traefik.http.routers.msceval.tls.certResolver=le

volumes:
portainer-data:
traefik-letsencrypt:
backend-logs:
backup-logs:
cassandra-data:
es-data:
es-logs:
provider-logs:
uptime-kuma:
ipfs-staging: # IPFS data on /export cf https://docs.ipfs.tech/install/run-ipfs-inside-docker/#set-up
ipfs-data: # IPFS data on /data/ipfs
swmath-state: # dedicated to the container swmath-swh

networks:
default:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1450