-
-
Notifications
You must be signed in to change notification settings - Fork 356
Expand file tree
/
Copy pathDockerfile
More file actions
302 lines (276 loc) · 11.1 KB
/
Dockerfile
File metadata and controls
302 lines (276 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# syntax=docker/dockerfile:1
# Simple Example Build Command:
# docker build \
# --tag crocodilestick/calibre-web-automated:dev \
# --build-arg="BUILD_DATE=27-09-2024 12:06" \
# --build-arg="VERSION=2.1.0-test-5" .
# Good guide on how to set up a buildx builder here:
# https://a-berahman.medium.com/simplifying-docker-multiplatform-builds-with-buildx-3d7efd670f58
# Multi-Platform Example Build & Push Command:
# docker buildx build \
# --push \
# --platform linux/amd64,linux/arm64, \
# --build-arg="BUILD_DATE=02-08-2024 20:52" \
# --build-arg="VERSION=2.1.0" \
# --tag crocodilestick/calibre-web-automated:latest .
# ==========================================================================
# STAGE 1: Dependencies - Install system packages and Python dependencies
# ==========================================================================
ARG CALIBRE_RELEASE=9.1.0
ARG KEPUBIFY_RELEASE=v4.0.4
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS dependencies
ARG CALIBRE_RELEASE
ARG KEPUBIFY_RELEASE
# Set the default shell for the following RUN instructions to bash instead of sh
SHELL ["/bin/bash", "-c"]
# STEP 1 - Install Required Packages
RUN \
# STEP 1.1 - Add deadsnakes PPA for Python 3.13 and install required apt packages
echo "**** add deadsnakes PPA for Python 3.13 ****" && \
apt-get update && \
apt-get install -y --no-install-recommends software-properties-common && \
add-apt-repository ppa:deadsnakes/ppa && \
apt-get update && \
echo "**** install build packages ****" && \
apt-get install -y --no-install-recommends \
build-essential \
libldap2-dev \
libsasl2-dev \
gettext \
python3.13-dev \
python3.13-venv \
curl && \
echo "**** install runtime packages ****" && \
apt-get install -y --no-install-recommends \
imagemagick \
ghostscript \
libldap2 \
libmagic1 \
libsasl2-2 \
libxi6 \
libxslt1.1 \
xdg-utils \
inotify-tools \
python3.13 \
nano \
sqlite3 \
zip && \
# STEP 1.2 - Install additional Calibre required packages
apt-get install -y --no-install-recommends \
libxtst6 \
libxrandr2 \
libxkbfile1 \
libxcomposite1 \
libxcursor1 \
libxfixes3 \
libxrender1 \
libopengl0 \
libnss3 \
libxkbcommon0 \
libegl1 \
libxdamage1 \
libgl1 \
libglx-mesa0 \
xz-utils \
binutils && \
# Install lsof 4.99.5 from source to fix hanging issue with 4.95 (issue #654)
echo "**** install lsof 4.99.5 from source ****" && \
LSOF_VERSION="4.99.5" && \
curl -L "https://github.com/lsof-org/lsof/archive/${LSOF_VERSION}.tar.gz" -o /tmp/lsof.tar.gz && \
cd /tmp && \
tar -xzf lsof.tar.gz && \
cd "lsof-${LSOF_VERSION}" && \
./Configure -n linux && \
make && \
cp lsof /usr/bin/lsof && \
chmod 755 /usr/bin/lsof && \
cd / && \
rm -rf /tmp/lsof* && \
# Create python3 symlink to point to python3.13
ln -sf /usr/bin/python3.13 /usr/bin/python3 && \
# Install pip for Python 3.13
curl -sS https://bootstrap.pypa.io/get-pip.py | python3.13
# STEP 2 - Set up Python virtual environment
RUN \
python3.13 -m venv /lsiopy && \
/lsiopy/bin/pip install -U --no-cache-dir \
pip \
wheel
# STEP 3 - Copy requirements files and install Python packages
# Copy only requirements files first to leverage Docker layer caching
COPY --chown=abc:abc requirements.txt optional-requirements.txt /app/calibre-web-automated/
RUN \
# STEP 3.1 - Installing the required python packages listed in 'requirements.txt' and 'optional-requirements.txt'
# HOWEVER, they are not pulled from PyPi directly, they are pulled from linuxserver's Ubuntu Wheel Index
# This is essentially a repository of precompiled some of the most popular packages with C/C++ source code
# This provides the install maximum compatibility with multiple different architectures including: x86_64, armv71 and aarch64
# You can read more about python wheels here: https://realpython.com/python-wheels/
/lsiopy/bin/pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/ubuntu/ -r \
/app/calibre-web-automated/requirements.txt -r /app/calibre-web-automated/optional-requirements.txt
# STEP 4 - Install kepubify
RUN \
echo "**** install kepubify ****" && \
if [[ $KEPUBIFY_RELEASE == 'newest' ]]; then \
KEPUBIFY_RELEASE=$(curl -sX GET "https://api.github.com/repos/pgaskin/kepubify/releases/latest" \
| awk '/tag_name/{print $4;exit}' FS='[""]'); \
fi && \
if [ "$(uname -m)" == "x86_64" ]; then \
curl -o \
/usr/bin/kepubify -L \
https://github.com/pgaskin/kepubify/releases/download/${KEPUBIFY_RELEASE}/kepubify-linux-64bit; \
elif [ "$(uname -m)" == "aarch64" ]; then \
curl -o \
/usr/bin/kepubify -L \
https://github.com/pgaskin/kepubify/releases/download/${KEPUBIFY_RELEASE}/kepubify-linux-arm64; \
fi && \
chmod +x /usr/bin/kepubify
# STEP 5 - Install Calibre
RUN \
# STEP 5.1 - Make the /app/calibre directory for the installed files
mkdir -p /app/calibre && \
# STEP 5.2 - Download the desired version of Calibre, determined by the CALIBRE_RELEASE variable and the architecture of the build environment
if [ "$(uname -m)" == "x86_64" ]; then \
curl -o \
/calibre.txz -L \
"https://download.calibre-ebook.com/${CALIBRE_RELEASE}/calibre-${CALIBRE_RELEASE}-x86_64.txz"; \
elif [ "$(uname -m)" == "aarch64" ]; then \
curl -o \
/calibre.txz -L \
"https://download.calibre-ebook.com/${CALIBRE_RELEASE}/calibre-${CALIBRE_RELEASE}-arm64.txz"; \
fi && \
# STEP 5.3 - Extract the downloaded file to /app/calibre
tar xf \
/calibre.txz -C \
/app/calibre && \
# STEP 5.3.1 - Remove the ABI tag from the extracted libQt6* files to allow them to be used on older kernels
# Removed in V3.1.4 because it was breaking Calibre features that require Qt6. Replaced with a kernel check in the cwa-init service
# STEP 5.4 - Delete the extracted calibre.txz to save space in final image
rm /calibre.txz
# ============================================================================
# STAGE 2: Final - Build the final runtime image
# ============================================================================
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS unrar-stage
FROM ghcr.io/linuxserver/unrar:latest AS unrar
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble
ARG BUILD_DATE
ARG VERSION
ARG CALIBRE_RELEASE
ARG KEPUBIFY_RELEASE
LABEL build_version="Version:- ${VERSION}"
LABEL build_date="${BUILD_DATE}"
LABEL maintainer="CrocodileStick"
# Set the default shell for the following RUN instructions to bash instead of sh
SHELL ["/bin/bash", "-c"]
# Copy installed dependencies from the dependencies stage
COPY --from=dependencies /lsiopy /lsiopy
COPY --from=dependencies /usr/bin/kepubify /usr/bin/kepubify
COPY --from=dependencies /app/calibre /app/calibre
COPY --from=dependencies /usr/bin/lsof /usr/bin/lsof
COPY --from=dependencies /usr/bin/python3.13 /usr/bin/python3.13
COPY --from=dependencies /usr/lib/python3.13 /usr/lib/python3.13
# Install only runtime packages (no build tools)
RUN \
echo "**** add deadsnakes PPA for Python 3.13 runtime ****" && \
apt-get update && \
apt-get install -y --no-install-recommends software-properties-common && \
add-apt-repository ppa:deadsnakes/ppa && \
apt-get update && \
echo "**** install runtime packages ****" && \
apt-get install -y --no-install-recommends \
imagemagick \
ghostscript \
libldap2 \
libmagic1 \
libsasl2-2 \
libxi6 \
libxslt1.1 \
xdg-utils \
inotify-tools \
python3.13 \
nano \
sqlite3 \
zip \
gettext \
libasound2t64 \
libxtst6 \
libxrandr2 \
libxkbfile1 \
libxcomposite1 \
libxcursor1 \
libxfixes3 \
libxrender1 \
libopengl0 \
libnss3 \
libxkbcommon0 \
libegl1 \
libxdamage1 \
libgl1 \
libglx-mesa0 \
xz-utils \
curl && \
# Create python3 symlink to point to python3.13
ln -sf /usr/bin/python3.13 /usr/bin/python3 && \
# Cleanup
apt-get -y purge software-properties-common && \
apt-get -y autoremove && \
rm -rf \
/tmp/* \
/var/lib/apt/lists/* \
/var/tmp/* \
/root/.cache
# STEP 6 - Copy application files
# Copy the rest of the application code (changes most frequently)
COPY --chown=abc:abc . /app/calibre-web-automated/
# STEP 7 - Configure application
RUN \
# STEP 7.1 - Move contents of /app/calibre-web-automated/root to / and delete the /app/calibre-web-automated/root directory
cp -R /app/calibre-web-automated/root/* / && \
rm -R /app/calibre-web-automated/root/ && \
# STEP 7.2 - Run CWA install script to make required dirs, set script permissions and add aliases for CLI commands ect.
chmod +x /app/calibre-web-automated/scripts/setup-cwa.sh && \
/app/calibre-web-automated/scripts/setup-cwa.sh && \
# STEP 7.3 - Create koplugin.zip from KOReader plugin folder
echo "~~~~ Creating koplugin.zip from KOReader plugin folder... ~~~~" && \
if [ -d "/app/calibre-web-automated/koreader/plugins/cwasync.koplugin" ]; then \
cd /app/calibre-web-automated/koreader/plugins && \
# Calculate digest of all files in the plugin for debugging purposes
echo "Calculating digest of plugin files..." && \
PLUGIN_DIGEST=$(find cwasync.koplugin -type f -name "*.lua" -o -name "*.json" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1) && \
echo "Plugin digest: $PLUGIN_DIGEST" && \
# Create a file named after the digest inside the plugin folder
echo "Plugin files digest: $PLUGIN_DIGEST" > cwasync.koplugin/${PLUGIN_DIGEST}.digest && \
echo "Build date: $(date)" >> cwasync.koplugin/${PLUGIN_DIGEST}.digest && \
echo "Files included:" >> cwasync.koplugin/${PLUGIN_DIGEST}.digest && \
find cwasync.koplugin -type f -name "*.lua" -o -name "*.json" | sort >> cwasync.koplugin/${PLUGIN_DIGEST}.digest && \
zip -r koplugin.zip cwasync.koplugin/ && \
echo "Created koplugin.zip from cwasync.koplugin folder with digest file: ${PLUGIN_DIGEST}.digest"; \
else \
echo "Warning: cwasync.koplugin folder not found, skipping zip creation"; \
fi && \
# STEP 7.4 - Move koplugin.zip to static directory
if [ -f "/app/calibre-web-automated/koreader/plugins/koplugin.zip" ]; then \
mkdir -p /app/calibre-web-automated/cps/static && \
cp /app/calibre-web-automated/koreader/plugins/koplugin.zip /app/calibre-web-automated/cps/static/ && \
echo "Moved koplugin.zip to static directory"; \
else \
echo "Warning: koplugin.zip not found, skipping move to static directory"; \
fi && \
# STEP 7.5 - ADD files referencing the versions of the installed main packages
echo "$VERSION" >| /app/CWA_RELEASE && \
echo "$KEPUBIFY_RELEASE" >| /app/KEPUBIFY_RELEASE && \
echo "$CALIBRE_RELEASE" > /CALIBRE_RELEASE
# Add unrar from unrar stage
COPY --from=unrar /usr/bin/unrar-ubuntu /usr/bin/unrar
# Set calibre environment variable
ENV CALIBRE_CONFIG_DIR=/config/.config/calibre
# Ports and volumes
WORKDIR /config
# The default port CWA listens on. Can be overridden with the CWA_PORT_OVERRIDE environment variable.
EXPOSE 8083
VOLUME /config
VOLUME /cwa-book-ingest
VOLUME /calibre-library
# Health check for container orchestration
# Uses shell form to support environment variable substitution for CWA_PORT_OVERRIDE
HEALTHCHECK --interval=30s --timeout=3s --start-period=120s --retries=3 \
CMD curl -f http://localhost:${CWA_PORT_OVERRIDE:-8083}/ || curl -f -k https://localhost:${CWA_PORT_OVERRIDE:-8083}/ || exit 1