Skip to content

Conversation

@parkervcp
Copy link
Contributor

@parkervcp parkervcp commented Jan 3, 2026

Fixes being able to install plugins
Resolves #2024
Resolves #2025

Fixes symlink for plugins
Resolves #2088

Adds symlink for server icons
Resolves #2054

Fixes loading environment variables
Resolves #2037

Integrates #2051 #2034 #2045 into a single PR.

Fixes being able to install plugins
Resolves pelican-dev#2024
Resolves pelican-dev#2025

Fixes symlink for plugins

Adds symlink for server icons
Resolves pelican-dev#2054

Fixes loading environment variables
Resolves pelican-dev#2056

Integrates pelican-dev#2051 pelican-dev#2034 pelican-dev#2045 into a single PR.
@coderabbitai
Copy link

coderabbitai bot commented Jan 3, 2026

📝 Walkthrough

Walkthrough

Adds runtime packages (zip, unzip, 7zip, bzip2-dev, yarn), adjusts symlinks for plugins and icons to persist under /pelican-data, and fixes .env loading in the entrypoint to split on newlines only; also creates /pelican-data/storage/icons at container startup.

Changes

Cohort / File(s) Summary
Docker image: runtime packages
Dockerfile, Dockerfile.dev
Install additional APK packages: zip, unzip, 7zip, bzip2-dev, and yarn in the final image to support plugin dependency installation.
Docker image: filesystem symlinks
Dockerfile, Dockerfile.dev
Added/changed symlinks: create /pelican-data/storage/icons/var/www/html/storage/app/public/icons; change /pelican-data/plugins to symlink to /var/www/html (replacing previous /var/www/html/plugins target). Minor reformatting of existing env/database symlink commands.
Entrypoint initialization
docker/entrypoint.sh
Load .env with xargs -d '\n' to avoid splitting on spaces, and ensure creation of /pelican-data/storage/icons alongside other persistent volume directories.

(Attention: verify plugin install flows that invoke composer/yarn at runtime and ensure permissions/ownership for newly created storage/icons and plugin paths.)

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Multiple Container Fixes' is vague and generic, using non-descriptive terms that don't clearly convey what the PR addresses. Use a more specific title that highlights the main changes, such as 'Fix plugin installation, symlinks, and environment variable parsing in Docker setup'.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code changes comprehensively address all linked issues: adds yarn/build tools for plugin dependencies (#2024, #2025), creates icon symlink (#2054), and fixes environment variable parsing (#2037).
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issues: dependency installation for plugins, symlink fixes for icons and plugins, and environment variable handling in entrypoint script.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description clearly maps changes to specific issues and is directly related to the changeset (plugin installation fixes, symlink corrections, icon persistence, environment variable loading).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
docker/entrypoint.sh (1)

6-6: Consider a more robust environment loading approach.

The xargs -d '\n' fix handles spaces in values, but the export $(...) pattern remains fragile with special characters (quotes, backticks, etc.). Consider using:

-  export $(grep -v '^#' .env | xargs -d '\n') # Fix is from https://github.com/pelican-dev/panel/pull/2045
+  set -a
+  . .env
+  set +a

This approach sources the file directly with automatic exporting enabled, avoiding word-splitting issues entirely.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3141fe6 and 7764903.

📒 Files selected for processing (3)
  • Dockerfile
  • Dockerfile.dev
  • docker/entrypoint.sh
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: QuintenQVD0
Repo: pelican-dev/panel PR: 2034
File: Dockerfile.base:12-12
Timestamp: 2025-12-24T09:21:58.780Z
Learning: Git is required at runtime in the Docker image for the plugin system's dependency installation, even though standard Packagist packages don't require it. This is needed in Dockerfile.base and other Dockerfiles.
📚 Learning: 2025-12-24T09:22:18.560Z
Learnt from: QuintenQVD0
Repo: pelican-dev/panel PR: 2034
File: Dockerfile.base:8-8
Timestamp: 2025-12-24T09:22:18.560Z
Learning: In the pelican-dev/panel project, the bz2 PHP extension is required in Dockerfile.base because a plugin in the plugin system depends on it for bzip2 compression functionality.

Applied to files:

  • Dockerfile
  • Dockerfile.dev
📚 Learning: 2025-12-24T09:21:52.260Z
Learnt from: QuintenQVD0
Repo: pelican-dev/panel PR: 2034
File: Dockerfile.base:12-12
Timestamp: 2025-12-24T09:21:52.260Z
Learning: Ensure that Dockerfiles install git at runtime where required for plugin system dependency installation. Update Dockerfile.base and any other Dockerfiles that build runtime images to include git in the runtime dependencies (not just for build-time), so plugin installation steps function correctly in the container.

Applied to files:

  • Dockerfile.dev
🪛 Shellcheck (0.11.0)
docker/entrypoint.sh

[warning] 6-6: Quote this to prevent word splitting.

(SC2046)

🔇 Additional comments (4)
docker/entrypoint.sh (1)

28-28: LGTM!

The addition of /pelican-data/storage/icons correctly ensures the directory exists for the new icons symlink, supporting the objective to persist icons across container restarts.

Dockerfile.dev (2)

70-74: Verify git is installed for plugin system.

The added packages (zip, unzip, 7zip, bzip2-dev, yarn) correctly support plugin installation per the PR objectives. However, based on learnings, git is required at runtime for the plugin system's dependency installation. Ensure git is included in the runtime packages.

🔎 Proposed fix to add git
 RUN apk add --no-cache \
     # packages for running the panel
     caddy ca-certificates supervisor supercronic fcgi coreutils \
     # required for installing plugins. Pulled from https://github.com/pelican-dev/panel/pull/2034
-    zip unzip 7zip bzip2-dev yarn 
+    zip unzip 7zip bzip2-dev yarn git

Based on learnings, git is required at runtime for plugin system dependency installation.


93-93: LGTM!

The icons symlink correctly ensures icon persistence across container restarts, directly addressing issue #2054.

Dockerfile (1)

88-88: LGTM!

The icons symlink correctly ensures persistence across container restarts, addressing issue #2054.

Copy link
Member

@rmartinoscar rmartinoscar left a comment

Choose a reason for hiding this comment

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

Other then the ln situation LGTM
Also it doesn't actually solves #2056 im still able to reproduce inside & outside of docker.

parkervcp and others added 2 commits January 6, 2026 12:30
Co-authored-by: MartinOscar <40749467+rmartinoscar@users.noreply.github.com>
Co-authored-by: MartinOscar <40749467+rmartinoscar@users.noreply.github.com>
@Drummss
Copy link

Drummss commented Jan 7, 2026

Out of interest, is there details on how the plugin system handles their composer packages? I couldn't find any code in the repo that suggested they are installed in the /plugins folder with the plugins themselves - but I may have missed it.

If they aren't installed into the /plugins folder, is there still work for this PR that is planned/being planned to address the vendor issues that I highlighted in #2025? If they are actually installed in the normal vendor folder, then I would imagine that when a Docker container is stopped, the composer plugins that were installed at the plugin installation stage would go missing if the plugin doesn't automatically reinstall them each startup - which seems like Docker container startup would be drastically extended.

I'm also not a heavy PHP developer, and so haven't worked with a plugin system that gives as much "power" as this one does - but I'm also wondering if plugins will have dependency conflicts if two plugins install different versions of the same plugin.

@rmartinoscar
Copy link
Member

rmartinoscar commented Jan 8, 2026

Out of interest, is there details on how the plugin system handles their composer packages? I couldn't find any code in the repo that suggested they are installed in the /plugins folder with the plugins themselves - but I may have missed it.

If they aren't installed into the /plugins folder, is there still work for this PR that is planned/being planned to address the vendor issues that I highlighted in #2025? If they are actually installed in the normal vendor folder, then I would imagine that when a Docker container is stopped, the composer plugins that were installed at the plugin installation stage would go missing if the plugin doesn't automatically reinstall them each startup - which seems like Docker container startup would be drastically extended.

I'm also not a heavy PHP developer, and so haven't worked with a plugin system that gives as much "power" as this one does - but I'm also wondering if plugins will have dependency conflicts if two plugins install different versions of the same plugin.

Plugins currently install dependancies in the main app vendor folder and adjust composer.json & composer.lock accordingly so i guess those should be volumes aswell 🤔

I'm also wondering if plugins will have dependency conflicts if two plugins install different versions of the same plugin.

If there's a conflict with existing plugin the new one will simplify fail to install until its resolved.

@Boy132 correct me if im wrong.

Good catch !

@Boy132
Copy link
Member

Boy132 commented Jan 8, 2026

[...] If there's a conflict with existing plugin the new one will simplify fail to install until its resolved.

@Boy132 correct me if im wrong.
[...]

If multiple plugins have the same dependency but different versions, the version of the plugin that is loaded last will be used.

public function manageComposerPackages(?array $newPackages = [], ?array $oldPackages = null): void
{
$newPackages ??= [];
$plugins = Plugin::query()->orderBy('load_order')->get();
foreach ($plugins as $plugin) {
if (!$plugin->composer_packages) {
continue;
}
if (!$plugin->shouldLoad()) {
continue;
}
try {
$pluginPackages = json_decode($plugin->composer_packages, true, 512, JSON_THROW_ON_ERROR);
$newPackages = array_merge($newPackages, $pluginPackages);
} catch (Exception $exception) {
report($exception);
}
}
$oldPackages = collect($oldPackages)
->filter(fn ($version, $package) => !array_key_exists($package, $newPackages))
->keys()
->unique()
->toArray();
if (count($oldPackages) > 0) {
$result = Process::path(base_path())->timeout(600)->run(['composer', 'remove', ...$oldPackages]);
if ($result->failed()) {
throw new Exception('Could not remove old composer packages: ' . $result->errorOutput());
}
}
$newPackages = collect($newPackages)
->map(fn ($version, $package) => "$package:$version")
->flatten()
->unique()
->toArray();
if (count($newPackages) > 0) {
$result = Process::path(base_path())->timeout(600)->run(['composer', 'require', ...$newPackages]);
if ($result->failed()) {
throw new Exception('Could not require new composer packages: ' . $result->errorOutput());
}
}
}

@mristau
Copy link
Contributor

mristau commented Jan 8, 2026

when i'm trying this entrypoint.sh it shows up this error in the logs, but after the error it shows all .env vars as

VARNAME='value'

external vars exist.
xargs: unrecognized option: d
BusyBox v1.37.0 (2025-12-16 14:19:28 UTC) multi-call binary.

Usage: xargs [OPTIONS] [PROG ARGS]

Run PROG on every item given by stdin

	-0	NUL terminated input
	-a FILE	Read from FILE instead of stdin
	-o	Reopen stdin as /dev/tty
	-r	Don't run command if input is empty
	-t	Print the command on stderr before execution
	-p	Ask user whether to run each command
	-E STR,-e[STR]	STR stops input processing
	-I STR	Replace STR within PROG ARGS with input line
	-n N	Pass no more than N args to PROG
	-s N	Pass command line of no more than N bytes
	-P N	Run up to N PROGs in parallel
	-x	Exit if size is exceeded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

6 participants