-
Notifications
You must be signed in to change notification settings - Fork 182
Docker setup #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Docker setup #3
Conversation
WalkthroughThe changes in this pull request introduce several new configuration files and scripts to the backend and frontend directories. A Changes
Assessment against linked issues
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Umm... did someone forget to read the style guide? Fix that PR title and let's try again! @akashsingh6474 |
|
Umm... did someone forget to read the style guide? Fix that PR title and let's try again! @coderabbitai[bot] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 23
🧹 Outside diff range and nitpick comments (10)
backend/.env.sample (1)
Line range hint
1-11: Consider adding documentation comments.To improve maintainability, consider adding comments to explain:
- The purpose of each environment variable
- Expected format/values
- Whether variables are required or optional
- Docker-specific configuration notes
Example format:
+# Server Configuration PORT=5050 + +# Database Configuration +# In Docker, 'mongodb' refers to the service name in docker-compose MONGODB_URI="mongodb://mongodb:27017/wanderlust"🧰 Tools
🪛 Gitleaks
9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
start_and_import.sh (1)
1-16: Add script documentation and validationThe script would benefit from better documentation and input validation.
#!/bin/bash + +# start_and_import.sh +# Description: Initializes Docker environment and imports sample data into MongoDB +# Usage: ./start_and_import.sh +# Requirements: +# - Docker and Docker Compose installed +# - MongoDB tools installed (mongoimport) +# - Running from repository root + +# Validate required tools +command -v docker-compose >/dev/null 2>&1 || { echo "Error: docker-compose is required but not installed"; exit 1; } +command -v mongoimport >/dev/null 2>&1 || { echo "Error: mongoimport is required but not installed"; exit 1; } +# Ensure we're in the correct directory +if [ ! -f "docker-compose.yml" ]; then + echo "Error: docker-compose.yml not found. Please run this script from the repository root." + exit 1 +fibackend/server.js (2)
Line range hint
8-20: Consider Docker-specific connection handling for Redis and MongoDBWhen running in Docker, the service connections need proper retry logic and container networking considerations.
Consider implementing:
- Connection retry logic for both Redis and MongoDB
- Environment-based connection strings for Docker networking
Here's a suggested implementation for more resilient connections:
// Connect to redis -connectToRedis(); +const MAX_RETRIES = 5; +const RETRY_INTERVAL = 5000; + +const connectWithRetry = async (service, connectFn, retries = MAX_RETRIES) => { + try { + await connectFn(); + console.log(`${service} connected successfully`); + } catch (error) { + if (retries === 0) { + console.error(`${service} connection failed after maximum retries:`, error); + process.exit(1); + } + console.log(`${service} connection failed, retrying in ${RETRY_INTERVAL}ms...`); + setTimeout(() => connectWithRetry(service, connectFn, retries - 1), RETRY_INTERVAL); + } +}; + +// Connect to services with retry +await connectWithRetry('Redis', connectToRedis); +await connectWithRetry('MongoDB', connectDB); + +app.listen(port, () => { + console.log(`Server is running on port ${port}`); +});
Line range hint
1-5: Consider using a configuration management approachFor better Docker support, consider centralizing configuration management.
Create a dedicated configuration module that handles different environments:
// config/config.js export const config = { port: process.env.PORT || 5050, redis: { host: process.env.REDIS_HOST || 'localhost', port: process.env.REDIS_PORT || 6379 }, mongodb: { url: process.env.MONGODB_URL || 'mongodb://localhost:27017/wanderlust' } };backend/Dockerfile (1)
7-11: Consider implementing dependency caching and audit.While the dependency installation works, there are a few improvements we could make:
- Add dependency caching to speed up builds
- Add security scanning
- The
--legacy-peer-depsflag might indicate compatibility issues that should be addressedConsider this enhancement:
# Copy package.json and package-lock.json first COPY package*.json ./ # Install dependencies -RUN npm install --legacy-peer-deps +RUN --mount=type=cache,target=/root/.npm \ + npm ci --only=production && \ + npm auditdocker-compose.yml (2)
38-39: Improve volume management configurationThe current volume configuration is too minimal. Consider using named volumes for all persistent data.
volumes: - data: + mongodb_data: + driver: local + redis_data: + driver: local
1-39: Consider adding essential production infrastructure componentsFor a production-ready setup, consider adding these additional services:
- Reverse Proxy (Nginx/Traefik) for SSL termination and routing
- Logging service (ELK stack or similar)
- Monitoring solution (Prometheus + Grafana)
- Backup service for MongoDB
- Load balancer for horizontal scaling
Would you like me to provide configurations for any of these components?
🧰 Tools
🪛 yamllint
[error] 32-32: trailing spaces
(trailing-spaces)
[warning] 34-34: wrong indentation: expected 6 but found 8
(indentation)
frontend/get-docker.sh (3)
361-376: Replace fixed sleep duration with a user promptThe script uses
sleep 20to provide users time to cancel the installation if Docker is already installed. This can be inconvenient, forcing users to wait unnecessarily.Consider replacing the fixed sleep with a user prompt to proceed when ready:
if command_exists docker; then cat >&2 <<-'EOF' Warning: the "docker" command appears to already exist on this system. If you already have Docker installed, this script can cause trouble, which is why we're displaying this warning and provide the opportunity to cancel the installation. If you installed the current Docker package using this script and are using it again to update Docker, you can safely ignore this message. You may press Ctrl+C now to abort this script. EOF - ( set -x; sleep 20 ) + read -p "Press [Enter] to continue or Ctrl+C to abort..." fiThis change enhances user experience by waiting for explicit confirmation before proceeding.
403-413: Recommend Docker Desktop for WSL usersThe script detects Windows Subsystem for Linux (WSL) and advises using Docker Desktop, but it still proceeds after a delay. In WSL environments, running Docker Engine directly may not be fully supported or could lead to issues.
Consider exiting the script after displaying the WSL notice to prevent unintended installation:
if is_wsl; then echo echo "WSL DETECTED: We recommend using Docker Desktop for Windows." echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/" echo cat >&2 <<-'EOF' You may press Ctrl+C now to abort this script. EOF - ( set -x; sleep 20 ) + exit 1 fiThis ensures users follow the recommended approach for Docker on WSL.
495-508: Handle missinglsb_releasecommand on Debian-based systemsThe script assumes that the
lsb_releasecommand exists, which might not be the case on minimal installations.Include a fallback method to determine the distribution version when
lsb_releaseis not available:ubuntu|debian|raspbian) pre_reqs="ca-certificates curl" + if ! command_exists lsb_release; then + pre_reqs="$pre_reqs lsb-release" + fi apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL" ( if ! is_dry_run; then set -x fi $sh_c 'apt-get -qq update >/dev/null' $sh_c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq install $pre_reqs >/dev/null"By ensuring
lsb-releaseis installed, the script can reliably detect the distribution version.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
frontend/nohup.outis excluded by!**/*.out
📒 Files selected for processing (13)
backend/.dockerignore(1 hunks)backend/.env.docker(1 hunks)backend/.env.sample(1 hunks)backend/1(1 hunks)backend/Dockerfile(1 hunks)backend/app.js(1 hunks)backend/server.js(1 hunks)command_history.txt(1 hunks)docker-compose.yml(1 hunks)frontend/.env.sample(1 hunks)frontend/Dockerfile(1 hunks)frontend/get-docker.sh(1 hunks)start_and_import.sh(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- backend/.dockerignore
- frontend/.env.sample
🧰 Additional context used
🪛 Gitleaks
backend/.env.docker
9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
backend/.env.sample
9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
backend/1
9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 LanguageTool
command_history.txt
[grammar] ~18-~18: After the number ‘18’, use a plural noun. Did you mean “histories”?
Context: ...17 history | grep "search_term" 18 history > command_history.txt
(CD_NNU)
🪛 yamllint
docker-compose.yml
[error] 32-32: trailing spaces
(trailing-spaces)
[warning] 34-34: wrong indentation: expected 6 but found 8
(indentation)
🔇 Additional comments (5)
command_history.txt (1)
1-18:
Remove this command history file and add it to .gitignore
This appears to be an accidentally committed command history file. Command history files often contain sensitive information and should not be tracked in version control.
Please take the following actions:
- Remove this file from the repository
- Add
command_history.txtto your.gitignorefile - Consider checking for any sensitive information that might have been exposed
Let's check if there are any other similar history files that should also be ignored:
🧰 Tools
🪛 LanguageTool
[grammar] ~18-~18: After the number ‘18’, use a plural noun. Did you mean “histories”?
Context: ...17 history | grep "search_term" 18 history > command_history.txt
(CD_NNU)
backend/Dockerfile (2)
1-5: LGTM: Build stage setup looks good!
The use of node:21-alpine as the base image is a good choice for minimizing image size while maintaining functionality.
1-33: Verify the impact of using node:21-alpine.
Node.js 21 is the latest version but may introduce compatibility issues. Ensure all dependencies and code are compatible with Node.js 21.
Let's check for potential compatibility issues:
✅ Verification successful
Node.js 21 compatibility verified with no major concerns
The codebase appears compatible with Node.js 21 based on the following findings:
- All dependencies use semantic versioning and are up-to-date, including critical packages like Express (4.21.1), Mongoose (8.8.0), and other core dependencies
- No explicit Node.js engine constraints in package.json
- The codebase uses standard Node.js features (no experimental features detected)
- The fetch API usage found in tests is using the
supertestlibrary, which is compatible with Node.js 21 - No deprecation warnings or version-specific issues found during dependency installation
The use of node:21-alpine in the Dockerfile is appropriate for this application.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check package.json for potential compatibility issues with Node.js 21
# Test: Check engine requirements in package.json
echo "Checking Node.js version requirements..."
jq '.engines?.node' package.json
# Test: Look for dependencies that might have Node.js version constraints
echo "Checking dependencies for Node.js version constraints..."
rg '"node":' package.json
Length of output: 281
Script:
#!/bin/bash
# Let's check the package.json content and dependencies
echo "Checking package.json content..."
cat package.json
# Also check for any specific Node.js API usage that might be version sensitive
echo -e "\nChecking for potentially version-sensitive Node.js API usage..."
rg -l 'worker_threads|test262|--experimental|--harmony|fetch|WebAssembly|performance.measureUserAgentSpecificMemory|import\.meta|queueMicrotask|diagnostics_channel|async_hooks|worker' --type js
# Check for any TypeScript configurations that might have Node.js version requirements
echo -e "\nChecking for TypeScript configurations..."
fd tsconfig.json --exec cat {}
Length of output: 2198
Script:
#!/bin/bash
# Let's check the backend's package.json since that's where the Dockerfile is located
echo "Checking backend package.json content..."
cat backend/package.json
# Check for fetch API usage in the files that were found
echo -e "\nChecking fetch API usage context..."
rg -C 2 'fetch' backend/routes/posts.js backend/tests/integration/controllers/posts-controller.test.js
# Check backend's dependencies installation logs for any warnings
echo -e "\nChecking for any npm warnings during installation..."
cd backend && npm install --dry-run 2>&1 || true
Length of output: 20900
docker-compose.yml (1)
1-2: LGTM! Good choice of Docker Compose version.
The version 3.8 is appropriate for modern Docker installations and provides access to all required features.
frontend/Dockerfile (1)
31-32: Verify the security implications of exposing port 5173.
Exposing the development server port might present security risks. Ensure proper network security measures are in place.
Let's check for any security configurations in the docker-compose file:
#!/bin/bash
# Check docker-compose network configuration
rg -A 5 "frontend:" docker-compose.yml| REDIS_URL="redis://18.212.168.92:6379" | ||
| FRONTEND_URL=http://18.212.168.92:5173 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove hardcoded IP addresses from sample configuration.
Hardcoding public IP addresses (18.212.168.92) in sample files:
- Creates maintenance overhead when IPs change
- May expose internal infrastructure details
- Makes the configuration less portable
Replace with appropriate placeholder values or service names for Docker.
Apply this diff:
-REDIS_URL="redis://18.212.168.92:6379"
-FRONTEND_URL=http://18.212.168.92:5173
+REDIS_URL="redis://redis:6379"
+FRONTEND_URL=http://frontend:5173📝 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.
| REDIS_URL="redis://18.212.168.92:6379" | |
| FRONTEND_URL=http://18.212.168.92:5173 | |
| REDIS_URL="redis://redis:6379" | |
| FRONTEND_URL=http://frontend:5173 |
| FRONTEND_URL=http://localhost:5173 | ||
| PORT=5050 | ||
| MONGODB_URI="mongodb://localhost/wanderlust" | ||
| REDIS_URL="redis://18.212.168.92:6379" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update MongoDB URI for Docker compatibility.
Using localhost in Docker containers won't work as expected since each container has its own network namespace. In a Docker environment, you should use the service name defined in docker-compose.
Apply this diff:
-MONGODB_URI="mongodb://localhost/wanderlust"
+MONGODB_URI="mongodb://mongodb:27017/wanderlust"📝 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.
| MONGODB_URI="mongodb://localhost/wanderlust" | |
| MONGODB_URI="mongodb://mongodb:27017/wanderlust" |
| REFRESH_COOKIE_MAXAGE=120000 | ||
| REFRESH_TOKEN_EXPIRES_IN='120s' | ||
| JWT_SECRET=70dd8b38486eee723ce2505f6db06f1ee503fde5eb06fc04687191a0ed665f3f98776902d2c89f6b993b1c579a87fedaf584c693a106f7cbf16e8b4e67e9d6df | ||
| NODE_ENV=Development No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove sensitive JWT_SECRET from sample file.
Exposing JWT secrets in version control, even in sample files, is a security risk. Replace it with a placeholder value.
Apply this diff:
-JWT_SECRET=70dd8b38486eee723ce2505f6db06f1ee503fde5eb06fc04687191a0ed665f3f98776902d2c89f6b993b1c579a87fedaf584c693a106f7cbf16e8b4e67e9d6df
+JWT_SECRET=your_jwt_secret_here📝 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.
| JWT_SECRET=70dd8b38486eee723ce2505f6db06f1ee503fde5eb06fc04687191a0ed665f3f98776902d2c89f6b993b1c579a87fedaf584c693a106f7cbf16e8b4e67e9d6df | |
| JWT_SECRET=your_jwt_secret_here |
🧰 Tools
🪛 Gitleaks
9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
| #!/bin/bash | ||
|
|
||
| # Step 1: Run Docker Compose | ||
| echo "Starting Docker Compose..." | ||
| docker-compose up -d |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for Docker Compose startup
The script should verify that Docker Compose started successfully before proceeding.
#!/bin/bash
+
+# Exit on error
+set -e
# Step 1: Run Docker Compose
echo "Starting Docker Compose..."
-docker-compose up -d
+if ! docker-compose up -d; then
+ echo "Error: Failed to start Docker Compose"
+ exit 1
+fi
+
+# Wait for services to be ready
+echo "Waiting for services to be healthy..."
+sleep 10 # Add appropriate wait time or implement health checkCommittable suggestion skipped: line range outside the PR's diff.
| # Step 3: Import MongoDB data | ||
| echo "Importing data into MongoDB..." | ||
| mongoimport --db wanderlust --collection posts --file ./data/sample_posts.json --jsonArray |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enhance MongoDB import reliability and security
The MongoDB import lacks error handling and authentication. Also, the data file existence should be verified.
# Step 3: Import MongoDB data
echo "Importing data into MongoDB..."
-mongoimport --db wanderlust --collection posts --file ./data/sample_posts.json --jsonArray
+
+# Check if data file exists
+if [ ! -f "./data/sample_posts.json" ]; then
+ echo "Error: Data file not found at ./data/sample_posts.json"
+ exit 1
+fi
+
+# Get MongoDB credentials from environment
+if [ -f ".env.docker" ]; then
+ source .env.docker
+fi
+
+# Wait for MongoDB to be ready
+echo "Waiting for MongoDB to be ready..."
+for i in {1..30}; do
+ if mongosh --eval "db.adminCommand('ping')" &>/dev/null; then
+ break
+ fi
+ echo "Waiting for MongoDB... ($i/30)"
+ sleep 1
+done
+
+# Import with authentication if credentials are available
+if [ -n "$MONGODB_USER" ] && [ -n "$MONGODB_PASSWORD" ]; then
+ mongoimport --username "$MONGODB_USER" --password "$MONGODB_PASSWORD" \
+ --db wanderlust --collection posts \
+ --file ./data/sample_posts.json --jsonArray
+else
+ mongoimport --db wanderlust --collection posts \
+ --file ./data/sample_posts.json --jsonArray
+fi📝 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.
| # Step 3: Import MongoDB data | |
| echo "Importing data into MongoDB..." | |
| mongoimport --db wanderlust --collection posts --file ./data/sample_posts.json --jsonArray | |
| # Step 3: Import MongoDB data | |
| echo "Importing data into MongoDB..." | |
| # Check if data file exists | |
| if [ ! -f "./data/sample_posts.json" ]; then | |
| echo "Error: Data file not found at ./data/sample_posts.json" | |
| exit 1 | |
| fi | |
| # Get MongoDB credentials from environment | |
| if [ -f ".env.docker" ]; then | |
| source .env.docker | |
| fi | |
| # Wait for MongoDB to be ready | |
| echo "Waiting for MongoDB to be ready..." | |
| for i in {1..30}; do | |
| if mongosh --eval "db.adminCommand('ping')" &>/dev/null; then | |
| break | |
| fi | |
| echo "Waiting for MongoDB... ($i/30)" | |
| sleep 1 | |
| done | |
| # Import with authentication if credentials are available | |
| if [ -n "$MONGODB_USER" ] && [ -n "$MONGODB_PASSWORD" ]; then | |
| mongoimport --username "$MONGODB_USER" --password "$MONGODB_PASSWORD" \ | |
| --db wanderlust --collection posts \ | |
| --file ./data/sample_posts.json --jsonArray | |
| else | |
| mongoimport --db wanderlust --collection posts \ | |
| --file ./data/sample_posts.json --jsonArray | |
| fi |
| @@ -0,0 +1,36 @@ | |||
| # Stage 1: Build the application | |||
| FROM node:21 AS build | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pin the Node.js version for reproducible builds.
Using node:21 without a specific version can lead to inconsistent builds. Pin to a specific version like node:21.5.0.
-FROM node:21 AS build
+FROM node:21.5.0 AS build📝 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.
| FROM node:21 AS build | |
| FROM node:21.5.0 AS build |
| # Specify the command to run your application | ||
| CMD ["npm", "run", "dev", "--", "--host"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't run the application in development mode in production.
Running with npm run dev in a production image exposes development features and debugging information that could be security risks.
-CMD ["npm", "run", "dev", "--", "--host"]
+CMD ["npm", "run", "start"]Additionally, ensure your package.json has a proper start script that runs the application in production mode.
Committable suggestion skipped: line range outside the PR's diff.
| # Copy the rest of the application files to the working directory | ||
| COPY . . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
🛠️ Refactor suggestion
Optimize Docker build by implementing proper layer caching and adding .dockerignore
The review comment is valid. The Dockerfile shows that dependencies are installed before copying all source files, but there's no .dockerignore file to optimize the build context. This can lead to:
- Unnecessary cache invalidation when unrelated files change
- Larger build context being sent to the Docker daemon
- Slower builds due to copying unnecessary files
Required actions:
- Create a
.dockerignorefile in the frontend directory with common exclusions:node_modules npm-debug.log .git .env .env.* !.env.sample dist build .DS_Store - Keep the current COPY operations order as it's already optimized (package*.json files first, then source files)
🔗 Analysis chain
Optimize layer caching by copying source files after installing dependencies.
The current order of COPY operations invalidates the cache unnecessarily. Consider copying only necessary files for the build.
Let's check if a .dockerignore exists:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for .dockerignore file
if [ -f frontend/.dockerignore ]; then
echo "Content of frontend/.dockerignore:"
cat frontend/.dockerignore
else
echo ".dockerignore not found in frontend directory!"
fi
Length of output: 251
Script:
#!/bin/bash
# Let's check for .dockerignore in the repository root and frontend directory
fd -t f .dockerignore
# Let's also examine the Dockerfile content for better context
if [ -f frontend/Dockerfile ]; then
echo "Content of frontend/Dockerfile:"
cat frontend/Dockerfile
fi
Length of output: 1049
| #!/bin/sh | ||
| set -e | ||
| # Docker Engine for Linux installation script. | ||
| # | ||
| # This script is intended as a convenient way to configure docker's package | ||
| # repositories and to install Docker Engine, This script is not recommended | ||
| # for production environments. Before running this script, make yourself familiar | ||
| # with potential risks and limitations, and refer to the installation manual | ||
| # at https://docs.docker.com/engine/install/ for alternative installation methods. | ||
| # | ||
| # The script: | ||
| # | ||
| # - Requires `root` or `sudo` privileges to run. | ||
| # - Attempts to detect your Linux distribution and version and configure your | ||
| # package management system for you. | ||
| # - Doesn't allow you to customize most installation parameters. | ||
| # - Installs dependencies and recommendations without asking for confirmation. | ||
| # - Installs the latest stable release (by default) of Docker CLI, Docker Engine, | ||
| # Docker Buildx, Docker Compose, containerd, and runc. When using this script | ||
| # to provision a machine, this may result in unexpected major version upgrades | ||
| # of these packages. Always test upgrades in a test environment before | ||
| # deploying to your production systems. | ||
| # - Isn't designed to upgrade an existing Docker installation. When using the | ||
| # script to update an existing installation, dependencies may not be updated | ||
| # to the expected version, resulting in outdated versions. | ||
| # | ||
| # Source code is available at https://github.com/docker/docker-install/ | ||
| # | ||
| # Usage | ||
| # ============================================================================== | ||
| # | ||
| # To install the latest stable versions of Docker CLI, Docker Engine, and their | ||
| # dependencies: | ||
| # | ||
| # 1. download the script | ||
| # | ||
| # $ curl -fsSL https://get.docker.com -o install-docker.sh | ||
| # | ||
| # 2. verify the script's content | ||
| # | ||
| # $ cat install-docker.sh | ||
| # | ||
| # 3. run the script with --dry-run to verify the steps it executes | ||
| # | ||
| # $ sh install-docker.sh --dry-run | ||
| # | ||
| # 4. run the script either as root, or using sudo to perform the installation. | ||
| # | ||
| # $ sudo sh install-docker.sh | ||
| # | ||
| # Command-line options | ||
| # ============================================================================== | ||
| # | ||
| # --version <VERSION> | ||
| # Use the --version option to install a specific version, for example: | ||
| # | ||
| # $ sudo sh install-docker.sh --version 23.0 | ||
| # | ||
| # --channel <stable|test> | ||
| # | ||
| # Use the --channel option to install from an alternative installation channel. | ||
| # The following example installs the latest versions from the "test" channel, | ||
| # which includes pre-releases (alpha, beta, rc): | ||
| # | ||
| # $ sudo sh install-docker.sh --channel test | ||
| # | ||
| # Alternatively, use the script at https://test.docker.com, which uses the test | ||
| # channel as default. | ||
| # | ||
| # --mirror <Aliyun|AzureChinaCloud> | ||
| # | ||
| # Use the --mirror option to install from a mirror supported by this script. | ||
| # Available mirrors are "Aliyun" (https://mirrors.aliyun.com/docker-ce), and | ||
| # "AzureChinaCloud" (https://mirror.azure.cn/docker-ce), for example: | ||
| # | ||
| # $ sudo sh install-docker.sh --mirror AzureChinaCloud | ||
| # | ||
| # ============================================================================== | ||
|
|
||
|
|
||
| # Git commit from https://github.com/docker/docker-install when | ||
| # the script was uploaded (Should only be modified by upload job): | ||
| SCRIPT_COMMIT_SHA="6d51e2cd8c04b38e1c2237820245f4fc262aca6c" | ||
|
|
||
| # strip "v" prefix if present | ||
| VERSION="${VERSION#v}" | ||
|
|
||
| # The channel to install from: | ||
| # * stable | ||
| # * test | ||
| DEFAULT_CHANNEL_VALUE="stable" | ||
| if [ -z "$CHANNEL" ]; then | ||
| CHANNEL=$DEFAULT_CHANNEL_VALUE | ||
| fi | ||
|
|
||
| DEFAULT_DOWNLOAD_URL="https://download.docker.com" | ||
| if [ -z "$DOWNLOAD_URL" ]; then | ||
| DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL | ||
| fi | ||
|
|
||
| DEFAULT_REPO_FILE="docker-ce.repo" | ||
| if [ -z "$REPO_FILE" ]; then | ||
| REPO_FILE="$DEFAULT_REPO_FILE" | ||
| fi | ||
|
|
||
| mirror='' | ||
| DRY_RUN=${DRY_RUN:-} | ||
| while [ $# -gt 0 ]; do | ||
| case "$1" in | ||
| --channel) | ||
| CHANNEL="$2" | ||
| shift | ||
| ;; | ||
| --dry-run) | ||
| DRY_RUN=1 | ||
| ;; | ||
| --mirror) | ||
| mirror="$2" | ||
| shift | ||
| ;; | ||
| --version) | ||
| VERSION="${2#v}" | ||
| shift | ||
| ;; | ||
| --*) | ||
| echo "Illegal option $1" | ||
| ;; | ||
| esac | ||
| shift $(( $# > 0 ? 1 : 0 )) | ||
| done | ||
|
|
||
| case "$mirror" in | ||
| Aliyun) | ||
| DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce" | ||
| ;; | ||
| AzureChinaCloud) | ||
| DOWNLOAD_URL="https://mirror.azure.cn/docker-ce" | ||
| ;; | ||
| "") | ||
| ;; | ||
| *) | ||
| >&2 echo "unknown mirror '$mirror': use either 'Aliyun', or 'AzureChinaCloud'." | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| case "$CHANNEL" in | ||
| stable|test) | ||
| ;; | ||
| *) | ||
| >&2 echo "unknown CHANNEL '$CHANNEL': use either stable or test." | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| command_exists() { | ||
| command -v "$@" > /dev/null 2>&1 | ||
| } | ||
|
|
||
| # version_gte checks if the version specified in $VERSION is at least the given | ||
| # SemVer (Maj.Minor[.Patch]), or CalVer (YY.MM) version.It returns 0 (success) | ||
| # if $VERSION is either unset (=latest) or newer or equal than the specified | ||
| # version, or returns 1 (fail) otherwise. | ||
| # | ||
| # examples: | ||
| # | ||
| # VERSION=23.0 | ||
| # version_gte 23.0 // 0 (success) | ||
| # version_gte 20.10 // 0 (success) | ||
| # version_gte 19.03 // 0 (success) | ||
| # version_gte 26.1 // 1 (fail) | ||
| version_gte() { | ||
| if [ -z "$VERSION" ]; then | ||
| return 0 | ||
| fi | ||
| version_compare "$VERSION" "$1" | ||
| } | ||
|
|
||
| # version_compare compares two version strings (either SemVer (Major.Minor.Path), | ||
| # or CalVer (YY.MM) version strings. It returns 0 (success) if version A is newer | ||
| # or equal than version B, or 1 (fail) otherwise. Patch releases and pre-release | ||
| # (-alpha/-beta) are not taken into account | ||
| # | ||
| # examples: | ||
| # | ||
| # version_compare 23.0.0 20.10 // 0 (success) | ||
| # version_compare 23.0 20.10 // 0 (success) | ||
| # version_compare 20.10 19.03 // 0 (success) | ||
| # version_compare 20.10 20.10 // 0 (success) | ||
| # version_compare 19.03 20.10 // 1 (fail) | ||
| version_compare() ( | ||
| set +x | ||
|
|
||
| yy_a="$(echo "$1" | cut -d'.' -f1)" | ||
| yy_b="$(echo "$2" | cut -d'.' -f1)" | ||
| if [ "$yy_a" -lt "$yy_b" ]; then | ||
| return 1 | ||
| fi | ||
| if [ "$yy_a" -gt "$yy_b" ]; then | ||
| return 0 | ||
| fi | ||
| mm_a="$(echo "$1" | cut -d'.' -f2)" | ||
| mm_b="$(echo "$2" | cut -d'.' -f2)" | ||
|
|
||
| # trim leading zeros to accommodate CalVer | ||
| mm_a="${mm_a#0}" | ||
| mm_b="${mm_b#0}" | ||
|
|
||
| if [ "${mm_a:-0}" -lt "${mm_b:-0}" ]; then | ||
| return 1 | ||
| fi | ||
|
|
||
| return 0 | ||
| ) | ||
|
|
||
| is_dry_run() { | ||
| if [ -z "$DRY_RUN" ]; then | ||
| return 1 | ||
| else | ||
| return 0 | ||
| fi | ||
| } | ||
|
|
||
| is_wsl() { | ||
| case "$(uname -r)" in | ||
| *microsoft* ) true ;; # WSL 2 | ||
| *Microsoft* ) true ;; # WSL 1 | ||
| * ) false;; | ||
| esac | ||
| } | ||
|
|
||
| is_darwin() { | ||
| case "$(uname -s)" in | ||
| *darwin* ) true ;; | ||
| *Darwin* ) true ;; | ||
| * ) false;; | ||
| esac | ||
| } | ||
|
|
||
| deprecation_notice() { | ||
| distro=$1 | ||
| distro_version=$2 | ||
| echo | ||
| printf "\033[91;1mDEPRECATION WARNING\033[0m\n" | ||
| printf " This Linux distribution (\033[1m%s %s\033[0m) reached end-of-life and is no longer supported by this script.\n" "$distro" "$distro_version" | ||
| echo " No updates or security fixes will be released for this distribution, and users are recommended" | ||
| echo " to upgrade to a currently maintained version of $distro." | ||
| echo | ||
| printf "Press \033[1mCtrl+C\033[0m now to abort this script, or wait for the installation to continue." | ||
| echo | ||
| sleep 10 | ||
| } | ||
|
|
||
| get_distribution() { | ||
| lsb_dist="" | ||
| # Every system that we officially support has /etc/os-release | ||
| if [ -r /etc/os-release ]; then | ||
| lsb_dist="$(. /etc/os-release && echo "$ID")" | ||
| fi | ||
| # Returning an empty string here should be alright since the | ||
| # case statements don't act unless you provide an actual value | ||
| echo "$lsb_dist" | ||
| } | ||
|
|
||
| echo_docker_as_nonroot() { | ||
| if is_dry_run; then | ||
| return | ||
| fi | ||
| if command_exists docker && [ -e /var/run/docker.sock ]; then | ||
| ( | ||
| set -x | ||
| $sh_c 'docker version' | ||
| ) || true | ||
| fi | ||
|
|
||
| # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output | ||
| echo | ||
| echo "================================================================================" | ||
| echo | ||
| if version_gte "20.10"; then | ||
| echo "To run Docker as a non-privileged user, consider setting up the" | ||
| echo "Docker daemon in rootless mode for your user:" | ||
| echo | ||
| echo " dockerd-rootless-setuptool.sh install" | ||
| echo | ||
| echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode." | ||
| echo | ||
| fi | ||
| echo | ||
| echo "To run the Docker daemon as a fully privileged service, but granting non-root" | ||
| echo "users access, refer to https://docs.docker.com/go/daemon-access/" | ||
| echo | ||
| echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent" | ||
| echo " to root access on the host. Refer to the 'Docker daemon attack surface'" | ||
| echo " documentation for details: https://docs.docker.com/go/attack-surface/" | ||
| echo | ||
| echo "================================================================================" | ||
| echo | ||
| } | ||
|
|
||
| # Check if this is a forked Linux distro | ||
| check_forked() { | ||
|
|
||
| # Check for lsb_release command existence, it usually exists in forked distros | ||
| if command_exists lsb_release; then | ||
| # Check if the `-u` option is supported | ||
| set +e | ||
| lsb_release -a -u > /dev/null 2>&1 | ||
| lsb_release_exit_code=$? | ||
| set -e | ||
|
|
||
| # Check if the command has exited successfully, it means we're in a forked distro | ||
| if [ "$lsb_release_exit_code" = "0" ]; then | ||
| # Print info about current distro | ||
| cat <<-EOF | ||
| You're using '$lsb_dist' version '$dist_version'. | ||
| EOF | ||
|
|
||
| # Get the upstream release info | ||
| lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]') | ||
| dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]') | ||
|
|
||
| # Print info about upstream distro | ||
| cat <<-EOF | ||
| Upstream release is '$lsb_dist' version '$dist_version'. | ||
| EOF | ||
| else | ||
| if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then | ||
| if [ "$lsb_dist" = "osmc" ]; then | ||
| # OSMC runs Raspbian | ||
| lsb_dist=raspbian | ||
| else | ||
| # We're Debian and don't even know it! | ||
| lsb_dist=debian | ||
| fi | ||
| dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" | ||
| case "$dist_version" in | ||
| 12) | ||
| dist_version="bookworm" | ||
| ;; | ||
| 11) | ||
| dist_version="bullseye" | ||
| ;; | ||
| 10) | ||
| dist_version="buster" | ||
| ;; | ||
| 9) | ||
| dist_version="stretch" | ||
| ;; | ||
| 8) | ||
| dist_version="jessie" | ||
| ;; | ||
| esac | ||
| fi | ||
| fi | ||
| fi | ||
| } | ||
|
|
||
| do_install() { | ||
| echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA" | ||
|
|
||
| if command_exists docker; then | ||
| cat >&2 <<-'EOF' | ||
| Warning: the "docker" command appears to already exist on this system. | ||
|
|
||
| If you already have Docker installed, this script can cause trouble, which is | ||
| why we're displaying this warning and provide the opportunity to cancel the | ||
| installation. | ||
|
|
||
| If you installed the current Docker package using this script and are using it | ||
| again to update Docker, you can safely ignore this message. | ||
|
|
||
| You may press Ctrl+C now to abort this script. | ||
| EOF | ||
| ( set -x; sleep 20 ) | ||
| fi | ||
|
|
||
| user="$(id -un 2>/dev/null || true)" | ||
|
|
||
| sh_c='sh -c' | ||
| if [ "$user" != 'root' ]; then | ||
| if command_exists sudo; then | ||
| sh_c='sudo -E sh -c' | ||
| elif command_exists su; then | ||
| sh_c='su -c' | ||
| else | ||
| cat >&2 <<-'EOF' | ||
| Error: this installer needs the ability to run commands as root. | ||
| We are unable to find either "sudo" or "su" available to make this happen. | ||
| EOF | ||
| exit 1 | ||
| fi | ||
| fi | ||
|
|
||
| if is_dry_run; then | ||
| sh_c="echo" | ||
| fi | ||
|
|
||
| # perform some very rudimentary platform detection | ||
| lsb_dist=$( get_distribution ) | ||
| lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')" | ||
|
|
||
| if is_wsl; then | ||
| echo | ||
| echo "WSL DETECTED: We recommend using Docker Desktop for Windows." | ||
| echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/" | ||
| echo | ||
| cat >&2 <<-'EOF' | ||
|
|
||
| You may press Ctrl+C now to abort this script. | ||
| EOF | ||
| ( set -x; sleep 20 ) | ||
| fi | ||
|
|
||
| case "$lsb_dist" in | ||
|
|
||
| ubuntu) | ||
| if command_exists lsb_release; then | ||
| dist_version="$(lsb_release --codename | cut -f2)" | ||
| fi | ||
| if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then | ||
| dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")" | ||
| fi | ||
| ;; | ||
|
|
||
| debian|raspbian) | ||
| dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" | ||
| case "$dist_version" in | ||
| 12) | ||
| dist_version="bookworm" | ||
| ;; | ||
| 11) | ||
| dist_version="bullseye" | ||
| ;; | ||
| 10) | ||
| dist_version="buster" | ||
| ;; | ||
| 9) | ||
| dist_version="stretch" | ||
| ;; | ||
| 8) | ||
| dist_version="jessie" | ||
| ;; | ||
| esac | ||
| ;; | ||
|
|
||
| centos|rhel) | ||
| if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then | ||
| dist_version="$(. /etc/os-release && echo "$VERSION_ID")" | ||
| fi | ||
| ;; | ||
|
|
||
| *) | ||
| if command_exists lsb_release; then | ||
| dist_version="$(lsb_release --release | cut -f2)" | ||
| fi | ||
| if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then | ||
| dist_version="$(. /etc/os-release && echo "$VERSION_ID")" | ||
| fi | ||
| ;; | ||
|
|
||
| esac | ||
|
|
||
| # Check if this is a forked Linux distro | ||
| check_forked | ||
|
|
||
| # Print deprecation warnings for distro versions that recently reached EOL, | ||
| # but may still be commonly used (especially LTS versions). | ||
| case "$lsb_dist.$dist_version" in | ||
| centos.8|centos.7|rhel.7) | ||
| deprecation_notice "$lsb_dist" "$dist_version" | ||
| ;; | ||
| debian.buster|debian.stretch|debian.jessie) | ||
| deprecation_notice "$lsb_dist" "$dist_version" | ||
| ;; | ||
| raspbian.buster|raspbian.stretch|raspbian.jessie) | ||
| deprecation_notice "$lsb_dist" "$dist_version" | ||
| ;; | ||
| ubuntu.bionic|ubuntu.xenial|ubuntu.trusty) | ||
| deprecation_notice "$lsb_dist" "$dist_version" | ||
| ;; | ||
| ubuntu.mantic|ubuntu.lunar|ubuntu.kinetic|ubuntu.impish|ubuntu.hirsute|ubuntu.groovy|ubuntu.eoan|ubuntu.disco|ubuntu.cosmic) | ||
| deprecation_notice "$lsb_dist" "$dist_version" | ||
| ;; | ||
| fedora.*) | ||
| if [ "$dist_version" -lt 39 ]; then | ||
| deprecation_notice "$lsb_dist" "$dist_version" | ||
| fi | ||
| ;; | ||
| esac | ||
|
|
||
| # Run setup for each distro accordingly | ||
| case "$lsb_dist" in | ||
| ubuntu|debian|raspbian) | ||
| pre_reqs="ca-certificates curl" | ||
| apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL" | ||
| ( | ||
| if ! is_dry_run; then | ||
| set -x | ||
| fi | ||
| $sh_c 'apt-get -qq update >/dev/null' | ||
| $sh_c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq install $pre_reqs >/dev/null" | ||
| $sh_c 'install -m 0755 -d /etc/apt/keyrings' | ||
| $sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc" | ||
| $sh_c "chmod a+r /etc/apt/keyrings/docker.asc" | ||
| $sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list" | ||
| $sh_c 'apt-get -qq update >/dev/null' | ||
| ) | ||
| pkg_version="" | ||
| if [ -n "$VERSION" ]; then | ||
| if is_dry_run; then | ||
| echo "# WARNING: VERSION pinning is not supported in DRY_RUN" | ||
| else | ||
| # Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel | ||
| pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/~ce~.*/g' | sed 's/-/.*/g')" | ||
| search_command="apt-cache madison docker-ce | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" | ||
| pkg_version="$($sh_c "$search_command")" | ||
| echo "INFO: Searching repository for VERSION '$VERSION'" | ||
| echo "INFO: $search_command" | ||
| if [ -z "$pkg_version" ]; then | ||
| echo | ||
| echo "ERROR: '$VERSION' not found amongst apt-cache madison results" | ||
| echo | ||
| exit 1 | ||
| fi | ||
| if version_gte "18.09"; then | ||
| search_command="apt-cache madison docker-ce-cli | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" | ||
| echo "INFO: $search_command" | ||
| cli_pkg_version="=$($sh_c "$search_command")" | ||
| fi | ||
| pkg_version="=$pkg_version" | ||
| fi | ||
| fi | ||
| ( | ||
| pkgs="docker-ce${pkg_version%=}" | ||
| if version_gte "18.09"; then | ||
| # older versions didn't ship the cli and containerd as separate packages | ||
| pkgs="$pkgs docker-ce-cli${cli_pkg_version%=} containerd.io" | ||
| fi | ||
| if version_gte "20.10"; then | ||
| pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" | ||
| fi | ||
| if version_gte "23.0"; then | ||
| pkgs="$pkgs docker-buildx-plugin" | ||
| fi | ||
| if ! is_dry_run; then | ||
| set -x | ||
| fi | ||
| $sh_c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq install $pkgs >/dev/null" | ||
| ) | ||
| echo_docker_as_nonroot | ||
| exit 0 | ||
| ;; | ||
| centos|fedora|rhel) | ||
| repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" | ||
| ( | ||
| if ! is_dry_run; then | ||
| set -x | ||
| fi | ||
| if command_exists dnf5; then | ||
| # $sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core" | ||
| # $sh_c "dnf5 config-manager addrepo --save-filename=docker-ce.repo --from-repofile='$repo_file_url'" | ||
|
|
||
| $sh_c "dnf -y -q --setopt=install_weak_deps=False install curl dnf-plugins-core" | ||
| # FIXME(thaJeztah); strip empty lines as workaround for https://github.com/rpm-software-management/dnf5/issues/1603 | ||
| TMP_REPO_FILE="$(mktemp --dry-run)" | ||
| $sh_c "curl -fsSL '$repo_file_url' | tr -s '\n' > '${TMP_REPO_FILE}'" | ||
| $sh_c "dnf5 config-manager addrepo --save-filename=docker-ce.repo --overwrite --from-repofile='${TMP_REPO_FILE}'" | ||
| $sh_c "rm -f '${TMP_REPO_FILE}'" | ||
|
|
||
| if [ "$CHANNEL" != "stable" ]; then | ||
| $sh_c "dnf5 config-manager setopt \"docker-ce-*.enabled=0\"" | ||
| $sh_c "dnf5 config-manager setopt \"docker-ce-$CHANNEL.enabled=1\"" | ||
| fi | ||
| $sh_c "dnf makecache" | ||
| elif command_exists dnf; then | ||
| $sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core" | ||
| $sh_c "dnf config-manager --add-repo $repo_file_url" | ||
|
|
||
| if [ "$CHANNEL" != "stable" ]; then | ||
| $sh_c "dnf config-manager --set-disabled \"docker-ce-*\"" | ||
| $sh_c "dnf config-manager --set-enabled \"docker-ce-$CHANNEL\"" | ||
| fi | ||
| $sh_c "dnf makecache" | ||
| else | ||
| $sh_c "yum -y -q install yum-utils" | ||
| $sh_c "yum-config-manager --add-repo $repo_file_url" | ||
|
|
||
| if [ "$CHANNEL" != "stable" ]; then | ||
| $sh_c "yum-config-manager --disable \"docker-ce-*\"" | ||
| $sh_c "yum-config-manager --enable \"docker-ce-$CHANNEL\"" | ||
| fi | ||
| $sh_c "yum makecache" | ||
| fi | ||
| ) | ||
| pkg_version="" | ||
| if command_exists dnf; then | ||
| pkg_manager="dnf" | ||
| pkg_manager_flags="-y -q --best" | ||
| else | ||
| pkg_manager="yum" | ||
| pkg_manager_flags="-y -q" | ||
| fi | ||
| if [ -n "$VERSION" ]; then | ||
| if is_dry_run; then | ||
| echo "# WARNING: VERSION pinning is not supported in DRY_RUN" | ||
| else | ||
| if [ "$lsb_dist" = "fedora" ]; then | ||
| pkg_suffix="fc$dist_version" | ||
| else | ||
| pkg_suffix="el" | ||
| fi | ||
| pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix" | ||
| search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" | ||
| pkg_version="$($sh_c "$search_command")" | ||
| echo "INFO: Searching repository for VERSION '$VERSION'" | ||
| echo "INFO: $search_command" | ||
| if [ -z "$pkg_version" ]; then | ||
| echo | ||
| echo "ERROR: '$VERSION' not found amongst $pkg_manager list results" | ||
| echo | ||
| exit 1 | ||
| fi | ||
| if version_gte "18.09"; then | ||
| # older versions don't support a cli package | ||
| search_command="$pkg_manager list --showduplicates docker-ce-cli | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" | ||
| cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)" | ||
| fi | ||
| # Cut out the epoch and prefix with a '-' | ||
| pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)" | ||
| fi | ||
| fi | ||
| ( | ||
| pkgs="docker-ce$pkg_version" | ||
| if version_gte "18.09"; then | ||
| # older versions didn't ship the cli and containerd as separate packages | ||
| if [ -n "$cli_pkg_version" ]; then | ||
| pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io" | ||
| else | ||
| pkgs="$pkgs docker-ce-cli containerd.io" | ||
| fi | ||
| fi | ||
| if version_gte "20.10"; then | ||
| pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" | ||
| fi | ||
| if version_gte "23.0"; then | ||
| pkgs="$pkgs docker-buildx-plugin" | ||
| fi | ||
| if ! is_dry_run; then | ||
| set -x | ||
| fi | ||
| $sh_c "$pkg_manager $pkg_manager_flags install $pkgs" | ||
| ) | ||
| echo_docker_as_nonroot | ||
| exit 0 | ||
| ;; | ||
| sles) | ||
| if [ "$(uname -m)" != "s390x" ]; then | ||
| echo "Packages for SLES are currently only available for s390x" | ||
| exit 1 | ||
| fi | ||
| repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" | ||
| pre_reqs="ca-certificates curl libseccomp2 awk" | ||
| ( | ||
| if ! is_dry_run; then | ||
| set -x | ||
| fi | ||
| $sh_c "zypper install -y $pre_reqs" | ||
| $sh_c "zypper addrepo $repo_file_url" | ||
| if ! is_dry_run; then | ||
| cat >&2 <<-'EOF' | ||
| WARNING!! | ||
| openSUSE repository (https://download.opensuse.org/repositories/security:/SELinux) will be enabled now. | ||
| Do you wish to continue? | ||
| You may press Ctrl+C now to abort this script. | ||
| EOF | ||
| ( set -x; sleep 30 ) | ||
| fi | ||
| opensuse_repo="https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/security:SELinux.repo" | ||
| $sh_c "zypper addrepo $opensuse_repo" | ||
| $sh_c "zypper --gpg-auto-import-keys refresh" | ||
| $sh_c "zypper lr -d" | ||
| ) | ||
| pkg_version="" | ||
| if [ -n "$VERSION" ]; then | ||
| if is_dry_run; then | ||
| echo "# WARNING: VERSION pinning is not supported in DRY_RUN" | ||
| else | ||
| pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g')" | ||
| search_command="zypper search -s --match-exact 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'" | ||
| pkg_version="$($sh_c "$search_command")" | ||
| echo "INFO: Searching repository for VERSION '$VERSION'" | ||
| echo "INFO: $search_command" | ||
| if [ -z "$pkg_version" ]; then | ||
| echo | ||
| echo "ERROR: '$VERSION' not found amongst zypper list results" | ||
| echo | ||
| exit 1 | ||
| fi | ||
| search_command="zypper search -s --match-exact 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'" | ||
| # It's okay for cli_pkg_version to be blank, since older versions don't support a cli package | ||
| cli_pkg_version="$($sh_c "$search_command")" | ||
| pkg_version="-$pkg_version" | ||
| fi | ||
| fi | ||
| ( | ||
| pkgs="docker-ce$pkg_version" | ||
| if version_gte "18.09"; then | ||
| if [ -n "$cli_pkg_version" ]; then | ||
| # older versions didn't ship the cli and containerd as separate packages | ||
| pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io" | ||
| else | ||
| pkgs="$pkgs docker-ce-cli containerd.io" | ||
| fi | ||
| fi | ||
| if version_gte "20.10"; then | ||
| pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" | ||
| fi | ||
| if version_gte "23.0"; then | ||
| pkgs="$pkgs docker-buildx-plugin" | ||
| fi | ||
| if ! is_dry_run; then | ||
| set -x | ||
| fi | ||
| $sh_c "zypper -q install -y $pkgs" | ||
| ) | ||
| echo_docker_as_nonroot | ||
| exit 0 | ||
| ;; | ||
| *) | ||
| if [ -z "$lsb_dist" ]; then | ||
| if is_darwin; then | ||
| echo | ||
| echo "ERROR: Unsupported operating system 'macOS'" | ||
| echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop" | ||
| echo | ||
| exit 1 | ||
| fi | ||
| fi | ||
| echo | ||
| echo "ERROR: Unsupported distribution '$lsb_dist'" | ||
| echo | ||
| exit 1 | ||
| ;; | ||
| esac | ||
| exit 1 | ||
| } | ||
|
|
||
| # wrapped up in a function so that we have some protection against only getting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider referencing the official Docker installation script instead of including it directly
Including the entire Docker installation script in the repository may lead to maintainability issues, as future updates to the official script won't be reflected here automatically. This could introduce security risks or compatibility problems if the script becomes outdated.
As an alternative, update your documentation to instruct users to download the official script directly from Docker's website:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.shThis ensures that users always obtain the latest, trusted version of the installation script.
| sh_c='sh -c' | ||
| if [ "$user" != 'root' ]; then | ||
| if command_exists sudo; then | ||
| sh_c='sudo -E sh -c' | ||
| elif command_exists su; then | ||
| sh_c='su -c' | ||
| else | ||
| cat >&2 <<-'EOF' | ||
| Error: this installer needs the ability to run commands as root. | ||
| We are unable to find either "sudo" or "su" available to make this happen. | ||
| EOF | ||
| exit 1 | ||
| fi | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve user privilege escalation handling
The script checks for sudo or su to gain root privileges but doesn't handle situations where neither is available or if su requires a password without a prompt.
Consider adding a more robust check and providing a clear error message if neither sudo nor su is available:
if [ "$user" != 'root' ]; then
if command_exists sudo; then
sh_c='sudo -E sh -c'
elif command_exists su; then
sh_c='su -c'
+ echo "Warning: Running commands with 'su' might require a root password."
+ else
+ cat >&2 <<-'EOF'
+ Error: This installer needs the ability to run commands as root.
+ Neither "sudo" nor "su" are available. Please install "sudo" or run this script as root.
+ EOF
+ exit 1
fi
fiThis modification ensures that the script fails gracefully when it cannot obtain the necessary privileges.
📝 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.
| sh_c='sh -c' | |
| if [ "$user" != 'root' ]; then | |
| if command_exists sudo; then | |
| sh_c='sudo -E sh -c' | |
| elif command_exists su; then | |
| sh_c='su -c' | |
| else | |
| cat >&2 <<-'EOF' | |
| Error: this installer needs the ability to run commands as root. | |
| We are unable to find either "sudo" or "su" available to make this happen. | |
| EOF | |
| exit 1 | |
| fi | |
| fi | |
| sh_c='sh -c' | |
| if [ "$user" != 'root' ]; then | |
| if command_exists sudo; then | |
| sh_c='sudo -E sh -c' | |
| elif command_exists su; then | |
| sh_c='su -c' | |
| echo "Warning: Running commands with 'su' might require a root password." | |
| else | |
| cat >&2 <<-'EOF' | |
| Error: This installer needs the ability to run commands as root. | |
| Neither "sudo" nor "su" are available. Please install "sudo" or run this script as root. | |
| EOF | |
| exit 1 | |
| fi | |
| fi |
|
Skipped: Cannot respond to another bot. |
Summary
Briefly describe the purpose of this PR.
Description
Explain in detail what this PR is all about. This should include the problem you're solving, the approach taken, and any technical details that reviewers need to know.
Images
Include any relevant images or diagrams that can help reviewers visualize the changes, if applicable
Issue(s) Addressed
Enter the issue number of the bug(s) that this PR fixes
Prerequisites
Summary by CodeRabbit
Release Notes
New Features
.dockerignorefile to optimize Docker image builds..env.dockerfor environment configuration with essential settings.docker-compose.ymlto define a multi-container setup for the application.get-docker.shscript for automated Docker installation on Linux.start_and_import.shfor starting Docker Compose and importing data into MongoDB.Bug Fixes
.env.samplefor consistency with new configurations.Refactor
Chores