-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
145 lines (127 loc) · 5.63 KB
/
Dockerfile
File metadata and controls
145 lines (127 loc) · 5.63 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
# Build stage
FROM python:3.14-slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Create virtual environment
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Install Python dependencies
COPY requirements.txt /tmp/
RUN pip install --no-cache-dir -r /tmp/requirements.txt
# Runtime stage
FROM python:3.14-slim
# OCI Labels
LABEL org.opencontainers.image.title="Reddit ModLog Wiki Publisher" \
org.opencontainers.image.description="Automated Reddit moderation log publisher to wiki pages" \
org.opencontainers.image.authors="baker-scripts" \
org.opencontainers.image.source="https://github.com/baker-scripts/RedditModLog" \
org.opencontainers.image.documentation="https://github.com/baker-scripts/RedditModLog/blob/main/README.md" \
org.opencontainers.image.licenses="GPL-3.0" \
org.opencontainers.image.vendor="baker-scripts" \
org.opencontainers.image.base.name="python:3.11-slim"
# Install runtime dependencies and s6-overlay for user management
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
xz-utils \
procps \
htop \
vim-tiny \
sqlite3 \
&& rm -rf /var/lib/apt/lists/*
# Install s6-overlay for proper init and user management
ARG S6_OVERLAY_VERSION=3.1.6.2
ARG TARGETARCH
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
RUN case ${TARGETARCH} in \
"amd64") S6_ARCH=x86_64 ;; \
"arm64") S6_ARCH=aarch64 ;; \
"arm/v7") S6_ARCH=arm ;; \
*) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \
esac && \
curl -L "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz" -o /tmp/s6-overlay-arch.tar.xz && \
tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz && \
tar -C / -Jxpf /tmp/s6-overlay-arch.tar.xz && \
rm /tmp/s6-overlay-*.tar.xz
# Create default user and group
RUN groupadd -g 1000 modlogbot && \
useradd -u 1000 -g modlogbot -d /config -s /bin/bash modlogbot
# Copy virtual environment from builder
COPY --from=builder /opt/venv /opt/venv
# Set environment variables
ENV PATH="/opt/venv/bin:$PATH" \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PUID=1000 \
PGID=1000 \
S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
DATABASE_PATH=/config/data/modlog.db \
LOGS_DIR=/config/logs
# Create application directories
RUN mkdir -p /config /config/data /config/logs /app /etc/s6-overlay/s6-rc.d/modlog-bot /etc/s6-overlay/s6-rc.d/init-modlogbot /etc/s6-overlay/scripts
# Create s6 init script for user/group management
RUN echo '#!/command/with-contenv bash\n\
set -e\n\
\n\
# Validate that we have either config file OR environment variables\n\
if [ ! -f /config/config.json ]; then\n\
echo "No config file found at /config/config.json, checking environment variables..."\n\
missing_vars=()\n\
[ -z "$REDDIT_CLIENT_ID" ] && missing_vars+=("REDDIT_CLIENT_ID")\n\
[ -z "$REDDIT_CLIENT_SECRET" ] && missing_vars+=("REDDIT_CLIENT_SECRET")\n\
[ -z "$REDDIT_USERNAME" ] && missing_vars+=("REDDIT_USERNAME")\n\
[ -z "$REDDIT_PASSWORD" ] && missing_vars+=("REDDIT_PASSWORD")\n\
[ -z "$SOURCE_SUBREDDIT" ] && missing_vars+=("SOURCE_SUBREDDIT")\n\
if [ ${#missing_vars[@]} -ne 0 ]; then\n\
echo "ERROR: No config file and missing required environment variables:" >&2\n\
printf " - %s\n" "${missing_vars[@]}" >&2\n\
echo "" >&2\n\
echo "Either mount a config file to /config/config.json OR set environment variables." >&2\n\
exit 1\n\
fi\n\
echo "Using environment variables for configuration"\n\
else\n\
echo "Using config file: /config/config.json"\n\
fi\n\
\n\
PUID=${PUID:-1000}\n\
PGID=${PGID:-1000}\n\
echo "Setting UID:GID to ${PUID}:${PGID}"\n\
\n\
groupmod -o -g "$PGID" modlogbot\n\
usermod -o -u "$PUID" modlogbot\n\
\n\
echo "Fixing ownership of /config"\n\
chown -R modlogbot:modlogbot /config\n\
\n\
if [ ! -f /config/data/modlog.db ]; then\n\
echo "Initializing database directory"\n\
touch /config/data/modlog.db\n\
chown modlogbot:modlogbot /config/data/modlog.db\n\
fi' > /etc/s6-overlay/scripts/init-modlogbot-run && \
chmod +x /etc/s6-overlay/scripts/init-modlogbot-run
# Create s6 service run script
RUN echo '#!/command/with-contenv bash\n\
cd /app\n\
exec s6-setuidgid modlogbot python modlog_wiki_publisher.py --config /config/config.json --continuous' > /etc/s6-overlay/scripts/modlog-bot-run && \
chmod +x /etc/s6-overlay/scripts/modlog-bot-run
# Setup s6 service definitions
RUN echo 'oneshot' > /etc/s6-overlay/s6-rc.d/init-modlogbot/type && \
echo '/etc/s6-overlay/scripts/init-modlogbot-run' > /etc/s6-overlay/s6-rc.d/init-modlogbot/up && \
echo 'longrun' > /etc/s6-overlay/s6-rc.d/modlog-bot/type && \
ln -s /etc/s6-overlay/scripts/modlog-bot-run /etc/s6-overlay/s6-rc.d/modlog-bot/run && \
echo 'init-modlogbot' > /etc/s6-overlay/s6-rc.d/modlog-bot/dependencies && \
touch /etc/s6-overlay/s6-rc.d/user/contents.d/init-modlogbot && \
touch /etc/s6-overlay/s6-rc.d/user/contents.d/modlog-bot
# Set working directory
WORKDIR /app
# Copy application files
COPY --chown=modlogbot:modlogbot modlog_wiki_publisher.py /app/
COPY --chown=modlogbot:modlogbot config_template.json /app/
# Health check
HEALTHCHECK --interval=5m --timeout=10s --start-period=30s --retries=3 \
CMD python -c "import os, sys; sys.exit(0 if os.path.exists(os.getenv('DATABASE_PATH', '/config/data/modlog.db')) else 1)"
# Use s6-overlay as entrypoint
ENTRYPOINT ["/init"]