Skip to content

Commit 14dab25

Browse files
committed
Added file-manager
1 parent 4ba1ddc commit 14dab25

File tree

9 files changed

+388
-0
lines changed

9 files changed

+388
-0
lines changed
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Publish file-manager Image
2+
3+
on:
4+
push:
5+
branches:
6+
- 'main'
7+
paths:
8+
- 'file-manager/*'
9+
tags:
10+
- 'file-manager-*'
11+
12+
jobs:
13+
file-manager:
14+
name: Publish file-manager Image
15+
runs-on: ubuntu-22.04
16+
steps:
17+
- uses: actions/[email protected]
18+
- name: Publish file-manager Image
19+
uses: openzim/docker-publish-action@v10
20+
with:
21+
image-name: offspot/file-manager
22+
on-master: dev
23+
build-args:
24+
VERSION={tag}
25+
tag-pattern: /^file-manager-([0-9.]+)$/
26+
restrict-to: offspot/container-images
27+
platforms: |
28+
linux/amd64
29+
linux/arm64
30+
context: file-manager
31+
registries: ghcr.io
32+
credentials:
33+
GHCRIO_USERNAME=${{ secrets.GHCR_USERNAME }}
34+
GHCRIO_TOKEN=${{ secrets.GHCR_TOKEN }}

file-manager/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
tinyfilemanager.php

file-manager/Dockerfile

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
FROM alpine:3.19
2+
LABEL org.opencontainers.image.source https://github.com/offspot/container-images
3+
4+
ENV WEBDIR "/var/www/html"
5+
6+
RUN apk add --no-cache \
7+
dumb-init \
8+
lighttpd \
9+
curl \
10+
php83-fpm php83-fileinfo php83-iconv php83-zip php83-mbstring php83-session php83-phar php83-ctype php83-posix
11+
12+
WORKDIR /var/www/html
13+
14+
RUN set -e \
15+
&& TFMREF="8e87afae5b744c3e23490000bf0d398d6d4a749c" \
16+
&& TFMPREFIX="https://raw.githubusercontent.com/prasathmani/tinyfilemanager/$TFMREF/" \
17+
&& mkdir -p $WEBDIR/assets/css $WEBDIR/assets/js $WEBDIR/assets/fonts \
18+
&& cd $WEBDIR/assets/css \
19+
&& curl -L -O https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css \
20+
&& curl -L -O https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.css.map \
21+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/min/dropzone.min.css \
22+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css \
23+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/vs.min.css \
24+
&& echo "CSS OK" \
25+
&& cd $WEBDIR/assets/fonts \
26+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/FontAwesome.otf \
27+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont.eot \
28+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont.svg \
29+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont.ttf \
30+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont.woff \
31+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2 \
32+
&& echo "FONTS OK" \
33+
&& cd $WEBDIR/assets/js \
34+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/ace/1.13.1/ace.js \
35+
&& curl -L -O https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js \
36+
&& curl -L -O https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.js.map \
37+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/min/dropzone.min.js \
38+
&& curl -L -O https://code.jquery.com/jquery-3.6.1.min.js \
39+
&& curl -L -O https://cdn.datatables.net/1.13.1/js/jquery.dataTables.min.js \
40+
&& curl -L -O https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js \
41+
&& echo "JS OK" \
42+
&& cd $WEBDIR \
43+
&& curl -L -O "$TFMPREFIX/translation.json" \
44+
&& curl -L -O "$TFMPREFIX/tinyfilemanager.php" \
45+
&& mkdir -p /data
46+
47+
RUN apk del curl
48+
49+
# patch TFM to disable in-php downloader
50+
51+
# replace head of file to change the external assets
52+
RUN lnum=$(grep -n -F "EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL" tinyfilemanager.php | cut -d ':' -f 1) \
53+
&& printf "<?php\n\
54+
\$config_file = __DIR__.'/config.php';\n\
55+
if (is_readable(\$config_file)) {\n\
56+
@include(\$config_file);\n\
57+
}\n" > index.php \
58+
&& tail -n +$lnum tinyfilemanager.php >> index.php \
59+
&& cat index.php
60+
61+
COPY lighttpd.conf /etc/lighttpd/lighttpd.conf
62+
COPY config.php /var/www/html
63+
COPY listing_auth.php /var/www/html
64+
COPY manager_auth.php /var/www/html
65+
COPY entrypoint /usr/local/bin/
66+
67+
# there are three modes:
68+
# - listing: lists the content of /data read-only
69+
# - manager: auth-required, /data is in read-write
70+
# - mixed: listing mode on / endpoint but manager on /admin/ endpoint
71+
ENV ACCESS_MODE "listing"
72+
73+
# authentication for manager and mixed modes (plaintext)
74+
ENV ADMIN_USERNAME "admin"
75+
ENV ADMIN_PASSWORD "admin@123"
76+
77+
# timezone to use for date/time (assuming host has date)
78+
# /!\ must be escaped! (slash)
79+
ENV UI_TIMEZONE "Etc\/UTC"
80+
81+
ENV UI_LANG "en"
82+
83+
ENV APP_URL ""
84+
85+
EXPOSE 80
86+
ENTRYPOINT ["/usr/bin/dumb-init", "--", "entrypoint"]
87+
CMD ["lighttpd", "-D", "-f", "/etc/lighttpd/lighttpd.conf"]

file-manager/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# file-browser
2+
3+
A [tinyfilemanager](https://github.com/prasathmani/tinyfilemanager)-based image for managing on-device files
4+
5+
## Usage
6+
7+
```sh
8+
docker run -p 80:80 -v /some/folder:/data:ro ghcr.io/offspot/file-manager
9+
```
10+
11+
## Configuration
12+
13+
Just mount your files tree to `/data`. If you don't plan on editing them, mount it read-only.
14+
15+
Configuration is done most via environment variables
16+
17+
| Variable | Default | Usage |
18+
| ------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
19+
| `ACCESS_MODE` | `listing` | One of `listing` (no auth, read-only), `manager` (auth-required, editable) and `mixed` (`listing` on `/` and `manager` on `/admin/`) |
20+
| `APP_URL` | | URL to the app. Not used in `mixed` mode. Allows better-looking URLs (`index.php` not visible) |
21+
| `UI_LANG` | `en` | UI Language (ISO-636-1), must be a supported one |
22+
| `UI_TIMEZONE` | `Etc/UTC` | Timezone to use to display file details. ⚠️ `/` must be escaped |
23+
| `ADMIN_USERNAME` | `admin` | Username for authentication (for `manager` and `mixed`) modes |
24+
| `ADMIN_PASSWORD` | `admin@123` | Password for authentication (for `manager` and `mixed`) modes |
25+

file-manager/config.php

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
error_reporting(E_ERROR | E_PARSE);
3+
//Default Configuration
4+
$CONFIG = '{"lang":"UI_LANG","error_reporting":false,"show_hidden":false,"hide_Cols":true,"theme":"light"}';
5+
6+
define('VERSION', '2.5.3-offspot');
7+
define('APP_TITLE', 'File Manager');
8+
$app_url = 'APP_URL';
9+
if ($app_url) {
10+
define('FM_SELF_URL', $app_url);
11+
}
12+
13+
// include auth file to switch modes
14+
$auth_file = __DIR__.'/auth.php';
15+
// echo $auth_file;
16+
if (is_readable($auth_file)) {
17+
@include($auth_file);
18+
}
19+
20+
// Readonly users
21+
// e.g. array('users', 'guest', ...)
22+
$readonly_users = array(
23+
);
24+
25+
// user specific directories
26+
// array('Username' => 'Directory path', 'Username2' => 'Directory path', ...)
27+
$directories_users = array();
28+
29+
// Enable highlight.js (https://highlightjs.org/) on view's page
30+
$use_highlightjs = true;
31+
32+
// highlight.js style
33+
// for dark theme use 'ir-black'
34+
$highlightjs_style = 'vs';
35+
36+
// Enable ace.js (https://ace.c9.io/) on view's page
37+
$edit_files = true;
38+
39+
// Default timezone for date() and time()
40+
// Doc - http://php.net/manual/en/timezones.php
41+
$default_timezone = 'UI_TIMEZONE';
42+
43+
// Root path for file manager
44+
// use absolute path of directory i.e: '/var/www/folder' or $_SERVER['DOCUMENT_ROOT'].'/folder'
45+
$root_path = '/data';
46+
47+
// Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder'
48+
// Will not working if $root_path will be outside of server document root
49+
$root_url = '/_download';
50+
51+
// Server hostname. Can set manually if wrong
52+
// $_SERVER['HTTP_HOST'].'/folder'
53+
$http_host = $_SERVER['HTTP_HOST'];
54+
55+
// input encoding for iconv
56+
$iconv_input_encoding = 'UTF-8';
57+
58+
// date() format for file modification date
59+
// Doc - https://www.php.net/manual/en/function.date.php
60+
$datetime_format = 'd/m/Y g:i A';
61+
62+
// Path display mode when viewing file information
63+
// 'full' => show full path
64+
// 'relative' => show path relative to root_path
65+
// 'host' => show path on the host
66+
$path_display_mode = 'relative';
67+
68+
// Allowed file extensions for create and rename files
69+
// e.g. 'txt,html,css,js'
70+
$allowed_file_extensions = '';
71+
72+
// Allowed file extensions for upload files
73+
// e.g. 'gif,png,jpg,html,txt'
74+
$allowed_upload_extensions = '';
75+
76+
// Favicon path. This can be either a full url to an .PNG image, or a path based on the document root.
77+
// full path, e.g http://example.com/favicon.png
78+
// local path, e.g images/icons/favicon.png
79+
$favicon_path = '';
80+
81+
// Files and folders to excluded from listing
82+
// e.g. array('myfile.html', 'personal-folder', '*.php', ...)
83+
$exclude_items = array();
84+
85+
// Online office Docs Viewer
86+
// Availabe rules are 'google', 'microsoft' or false
87+
// Google => View documents using Google Docs Viewer
88+
// Microsoft => View documents using Microsoft Web Apps Viewer
89+
// false => disable online doc viewer
90+
$online_viewer = 'false';
91+
92+
// Sticky Nav bar
93+
// true => enable sticky header
94+
// false => disable sticky header
95+
$sticky_navbar = false;
96+
97+
// Maximum file upload size
98+
// Increase the following values in php.ini to work properly
99+
// memory_limit, upload_max_filesize, post_max_size
100+
$max_upload_size_bytes = 20000000000; // size 5,000,000,000 bytes (~5GB)
101+
102+
// chunk size used for upload
103+
// eg. decrease to 1MB if nginx reports problem 413 entity too large
104+
$upload_chunk_size_bytes = 2000000; // chunk size 2,000,000 bytes (~2MB)
105+
106+
// Possible rules are 'OFF', 'AND' or 'OR'
107+
// OFF => Don't check connection IP, defaults to OFF
108+
// AND => Connection must be on the whitelist, and not on the blacklist
109+
// OR => Connection must be on the whitelist, or not on the blacklist
110+
$ip_ruleset = 'OFF';
111+
112+
// Should users be notified of their block?
113+
$ip_silent = true;
114+
115+
// IP-addresses, both ipv4 and ipv6
116+
$ip_whitelist = array(
117+
'127.0.0.1', // local ipv4
118+
'::1' // local ipv6
119+
);
120+
121+
// IP-addresses, both ipv4 and ipv6
122+
$ip_blacklist = array(
123+
'0.0.0.0', // non-routable meta ipv4
124+
'::' // non-routable meta ipv6
125+
);
126+
127+
// External CDN resources that can be used in the HTML (replace for GDPR compliance)
128+
$external = array(
129+
'css-bootstrap' => '<link href="/assets/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">',
130+
'css-dropzone' => '<link href="/assets/css/dropzone.min.css" rel="stylesheet">',
131+
'css-font-awesome' => '<link rel="stylesheet" href="/assets/css/font-awesome.min.css" crossorigin="anonymous">',
132+
'css-highlightjs' => '<link rel="stylesheet" href="/assets/css/' . $highlightjs_style . '.min.css">',
133+
'js-ace' => '<script src="/assets/js/ace.js"></script>',
134+
'js-bootstrap' => '<script src="/assets/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>',
135+
'js-dropzone' => '<script src="/assets/js/dropzone.min.js"></script>',
136+
'js-jquery' => '<script src="/assets/js/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>',
137+
'js-jquery-datatables' => '<script src="/assets/js/jquery.dataTables.min.js" crossorigin="anonymous" defer></script>',
138+
'js-highlightjs' => '<script src="/assets/js/highlight.min.js"></script>',
139+
'pre-jsdelivr' => '<style type="text/css">form[action*="dl="], a[href*="&dl="] { background-color: red; display:none !important; }\na[href*="/_download/"] { } i.fa.fa-link::before { content: "\f019" !important; }</style>',
140+
'pre-cloudflare' => ''
141+
);
142+
143+
?>

file-manager/entrypoint

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/sh
2+
set -e
3+
4+
echo "set credentials"
5+
sed -i "s/ADMIN_USERNAME/${ADMIN_USERNAME}/g" manager_auth.php
6+
sed -i "s/ADMIN_PASSWORD/${ADMIN_PASSWORD}/g" manager_auth.php
7+
8+
# mixed mode cannot set APP_URL as there are two apps
9+
if [[ "$ACCESS_MODE" = "mixed" ]]
10+
then
11+
unset APP_URL
12+
fi
13+
14+
# static replacement for envs (so we can keep clear_env=yes)
15+
echo "set statics"
16+
sed -i "s/UI_TIMEZONE/${UI_TIMEZONE}/g" config.php
17+
sed -i "s/UI_LANG/${UI_LANG}/g" config.php
18+
sed -i "s/APP_URL/${APP_URL}/g" config.php
19+
20+
echo "configuring for ${ACCESS_MODE}"
21+
if [[ "$ACCESS_MODE" = "listing" ]]
22+
then
23+
ln -s listing_auth.php auth.php
24+
25+
elif [[ "$ACCESS_MODE" = "manager" ]]
26+
then
27+
28+
ln -s manager_auth.php auth.php
29+
30+
elif [[ "$ACCESS_MODE" = "mixed" ]]
31+
then
32+
mkdir -p admin
33+
cd admin
34+
cp ../index.php index.php
35+
cp ../config.php config.php
36+
cp ../manager_auth.php auth.php
37+
cd ..
38+
ln -s listing_auth.php auth.php
39+
else
40+
echo "Unsupported mode: ${ACCESS_MODE}"
41+
exit 1
42+
fi
43+
44+
ls -l
45+
cat config.php
46+
cat auth.php
47+
cat manager_auth.php
48+
49+
php-fpm83 -D
50+
51+
exec "$@"

file-manager/lighttpd.conf

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
server.document-root = "/var/www/html"
2+
3+
server.modules += ("mod_accesslog")
4+
server.modules += ("mod_deflate")
5+
server.errorlog = "/dev/fd/2"
6+
accesslog.filename = "/dev/fd/2"
7+
8+
server.modules += ( "mod_fastcgi" )
9+
fastcgi.server = ( ".php" => ((
10+
"host" => "127.0.0.1",
11+
"port" => "9000"
12+
)))
13+
14+
index-file.names = ( "index.html", "index.php" )
15+
16+
server.modules += ("mod_alias")
17+
alias.url = ( "/_download/" => "/data/" )

file-manager/listing_auth.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
// Auth with login/password
4+
// set true/false to enable/disable it
5+
// Is independent from IP white- and blacklisting
6+
$use_auth = false;
7+
8+
// Global readonly, including when auth is not being used
9+
$global_readonly = true;
10+
11+
12+
?>

file-manager/manager_auth.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
// Auth with login/password
4+
// set true/false to enable/disable it
5+
// Is independent from IP white- and blacklisting
6+
$use_auth = true;
7+
8+
// Global readonly, including when auth is not being used
9+
$global_readonly = false;
10+
11+
// Login user name and password
12+
// Users: array('Username' => 'Password', 'Username2' => 'Password2', ...)
13+
// Generate secure password hash - https://tinyfilemanager.github.io/docs/pwd.html
14+
$auth_users = array(
15+
'ADMIN_USERNAME' => password_hash('ADMIN_PASSWORD', PASSWORD_DEFAULT),
16+
);
17+
18+
?>

0 commit comments

Comments
 (0)