This guide covers building, running, and managing Source Code Portal Docker containers.
- Building Docker Images
- Running Containers
- Configuration
- Docker Compose
- Advanced Topics
- Troubleshooting
Build from the official Maven repository:
docker build -t cantara/sourcecodeportal .This downloads the latest released version from Maven Central.
Specify a version using the DOCKER_TAG build argument:
docker build --build-arg DOCKER_TAG=0.10.17 -t cantara/sourcecodeportal:0.10.17 .To build from local source code instead of Maven:
# Build JAR first
mvn clean package -DskipTests
# Build Docker image with local JAR
docker build -f Dockerfile.local -t cantara/sourcecodeportal:local .Create Dockerfile.local:
FROM eclipse-temurin:21-jre-alpine
# Create app user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Create app directory
WORKDIR /home/sourcecodeportal
RUN chown appuser:appgroup /home/sourcecodeportal
# Copy local JAR
COPY --chown=appuser:appgroup target/source-code-portal-*.jar app.jar
# Switch to non-root user
USER appuser
# Expose port
EXPOSE 9090
# Run application
ENTRYPOINT ["java", "-jar", "app.jar"]# Check image exists
docker images | grep sourcecodeportal
# Inspect image
docker inspect cantara/sourcecodeportaldocker run -p 9090:9090 cantara/sourcecodeportalAccess the application at http://localhost:9090
docker run \
--env github.oauth2.client.clientId=YOUR_CLIENT_ID \
--env github.oauth2.client.clientSecret=YOUR_CLIENT_SECRET \
--rm -p 9090:9090 \
cantara/sourcecodeportalCreate .env file:
# GitHub Configuration
github.oauth2.client.clientId=your_client_id
github.oauth2.client.clientSecret=your_client_secret
github.client.accessToken=ghp_your_access_token
github.organization=YourOrg
# Server Configuration
server.port=9090Run with environment file:
docker run --env-file .env -p 9090:9090 cantara/sourcecodeportaldocker run -d \
--name scp \
--env-file .env \
-p 9090:9090 \
--restart unless-stopped \
cantara/sourcecodeportalMount configuration files:
docker run -d \
--name scp \
-v $(pwd)/config.json:/home/sourcecodeportal/config_override/conf/config.json:ro \
-v $(pwd)/security.properties:/home/sourcecodeportal/config_override/security.properties:ro \
-v $(pwd)/logs:/home/sourcecodeportal/logs \
-p 9090:9090 \
cantara/sourcecodeportalAll configuration properties can be set via environment variables with SCP_ prefix:
docker run \
-e SCP_GITHUB_ACCESS_TOKEN=ghp_token \
-e SCP_GITHUB_ORGANIZATION=Cantara \
-e SCP_SERVER_PORT=9090 \
-e SCP_CACHE_TTL=30 \
-p 9090:9090 \
cantara/sourcecodeportaldocker run \
-v $(pwd)/config.json:/home/sourcecodeportal/config_override/conf/config.json:ro \
-p 9090:9090 \
cantara/sourcecodeportal# Find container ID
docker ps
CONTAINER_ID=abc123def456
# Copy config file
docker cp config.json $CONTAINER_ID:/home/sourcecodeportal/config_override/conf/config.json
# Restart container to pick up changes
docker restart $CONTAINER_ID# Get full container ID
FULL_ID=$(docker inspect -f '{{.Id}}' cantara/sourcecodeportal)
# Copy config (requires root or Docker volume access)
sudo cp config.json /var/lib/docker/aufs/mnt/$FULL_ID/home/sourcecodeportal/config_override/conf/config.jsonNote: This method is deprecated and may not work with newer Docker storage drivers.
Add health check to Docker run:
docker run -d \
--name scp \
--health-cmd="curl -f http://localhost:9090/actuator/health || exit 1" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
--health-start-period=60s \
-p 9090:9090 \
cantara/sourcecodeportalCheck health status:
docker ps # Shows health status
docker inspect scp | grep -A 10 HealthCreate docker-compose.yml:
version: '3.8'
services:
sourcecodeportal:
image: cantara/sourcecodeportal:latest
container_name: scp
ports:
- "9090:9090"
environment:
- github.oauth2.client.clientId=${GITHUB_CLIENT_ID}
- github.oauth2.client.clientSecret=${GITHUB_CLIENT_SECRET}
- github.client.accessToken=${GITHUB_ACCESS_TOKEN}
- github.organization=${GITHUB_ORGANIZATION}
volumes:
- ./config.json:/home/sourcecodeportal/config_override/conf/config.json:ro
- ./logs:/home/sourcecodeportal/logs
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9090/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60sCreate docker-compose.prod.yml:
version: '3.8'
services:
sourcecodeportal:
image: cantara/sourcecodeportal:0.10.17
container_name: scp-prod
ports:
- "80:9090"
environment:
- SPRING_PROFILES_ACTIVE=prod
- github.oauth2.client.clientId=${GITHUB_CLIENT_ID}
- github.oauth2.client.clientSecret=${GITHUB_CLIENT_SECRET}
- github.client.accessToken=${GITHUB_ACCESS_TOKEN}
- github.organization=${GITHUB_ORGANIZATION}
volumes:
- ./config.json:/home/sourcecodeportal/config_override/conf/config.json:ro
- ./security.properties:/home/sourcecodeportal/config_override/security.properties:ro
- scp-logs:/home/sourcecodeportal/logs
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9090/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
scp-logs:
driver: local# Start services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
# Restart services
docker-compose restart
# Pull latest images
docker-compose pull
# Recreate containers with new config
docker-compose up -d --force-recreateCreate docker-compose.build.yml:
version: '3.8'
services:
sourcecodeportal:
build:
context: .
dockerfile: Dockerfile
args:
DOCKER_TAG: 0.10.17
container_name: scp-built
ports:
- "9090:9090"
env_file:
- .env
volumes:
- ./config.json:/home/sourcecodeportal/config_override/conf/config.json:ro
restart: unless-stoppedBuild and run:
docker-compose -f docker-compose.build.yml build
docker-compose -f docker-compose.build.yml up -dOptimize Docker image size with multi-stage build:
# Stage 1: Build
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 2: Runtime
FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /home/sourcecodeportal
COPY --from=builder --chown=appuser:appgroup /app/target/source-code-portal-*.jar app.jar
USER appuser
EXPOSE 9090
ENTRYPOINT ["java", "-jar", "app.jar"]Limit container resources:
docker run -d \
--name scp \
--cpus="2" \
--memory="2g" \
--memory-reservation="1g" \
-p 9090:9090 \
cantara/sourcecodeportaldocker run -d \
--name scp \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
-p 9090:9090 \
cantara/sourcecodeportaldocker run -d \
--name scp \
--log-driver syslog \
--log-opt syslog-address=tcp://192.168.1.100:514 \
-p 9090:9090 \
cantara/sourcecodeportal# Create network
docker network create scp-network
# Run container on network
docker run -d \
--name scp \
--network scp-network \
-p 9090:9090 \
cantara/sourcecodeportaldocker run -d \
--name scp \
--network host \
cantara/sourcecodeportalNote: With host network, the container shares the host's network namespace.
Generate GitHub access token using Docker:
docker run -it \
-e SCP_github.oauth2.client.clientId=YOUR_CLIENT_ID \
-e SCP_github.oauth2.client.clientSecret=YOUR_CLIENT_SECRET \
cantara/sourcecodeportal /github-access-tokenThis runs the OAuth flow to obtain a GitHub personal access token.
Check logs:
docker logs scp
docker logs -f scp # Follow logsCommon issues:
- Port 9090 already in use: Use
-p 8080:9090to map to different port - Missing configuration: Ensure environment variables are set
- Permission issues: Check volume mount permissions
Check restart policy and logs:
docker inspect scp | grep -A 5 RestartPolicy
docker logs --tail 100 scpDisable restart temporarily:
docker update --restart=no scp
docker restart scp
docker logs -f scpCheck if container is running:
docker psCheck port mapping:
docker port scpTest from within container:
docker exec scp curl -f http://localhost:9090/actuator/healthTest from host:
curl http://localhost:9090/actuator/healthCheck memory stats:
docker stats scpLimit memory:
docker update --memory="2g" scp
docker restart scpVerify volume mounts:
docker inspect scp | grep -A 10 MountsVerify file inside container:
docker exec scp cat /home/sourcecodeportal/config_override/conf/config.jsonCheck rate limit status:
docker exec scp curl http://localhost:9090/actuator/health/github- Use specific version tags in production (not
latest) - Set resource limits to prevent resource exhaustion
- Configure health checks for automatic restart on failure
- Use volume mounts for configuration files
- Store secrets in environment variables, not in images
- Enable logging with rotation to prevent disk fill
- Use Docker Compose for multi-container setups
- Regularly update base images for security patches
- Monitor container health via
/actuator/health - Backup configuration files before updates
- Deployment Guide - Full deployment options
- Monitoring Guide - Set up monitoring and metrics
- Troubleshooting Guide - Detailed troubleshooting