forked from onetimesecret/onetimesecret
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Dockerfile
210 lines (183 loc) · 6.2 KB
/
Dockerfile
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
# syntax=docker/dockerfile:experimental@sha256:600e5c62eedff338b3f7a0850beb7c05866e0ef27b2d2e8c02aa468e78496ff5
##
# ONETIME SECRET - DOCKER IMAGE - 2024-07-30
#
#
# To build and use this image, you need to copy the example
# configuration files into place:
#
# $ cp --preserve --no-clobber ./etc/config.example ./etc/config
#
# - and -
#
# $ cp --preserve --no-clobber .env.example .env
#
# The default values work as-is but it's a good practice to have
# a look and customize as you like (partcularly the mast secret
# `SECRET` and redis password in `REDIS_URL`).
#
#
# USAGE (Docker):
#
# First, start a Redis database with persistence enabled:
#
# $ docker run -p 6379:6379 --name redis -d redis
#
# Then build and run this image, specifying the redis URL:
#
# $ docker run -p 3000:3000 -d --name onetimesecret \
# -e REDIS_URL="redis://172.17.0.2:6379/0" \
# -e RACK_ENV=production \
# onetimesecret
#
# It will be accessible on http://localhost:3000.
#
#
# USAGE (Docker Compose):
#
# When bringing up a frontend container for the first time, makes
# sure the database container is already running and attached.
#
# $ docker-compose up -d redis
# $ docker-compose up --attach-dependencies --build onetime
#
# If you ever need to force rebuild a container:
#
# $ docker-compose build --no-cache onetime
#
# ----------------------------------------------------------------
# NOTE: All Docker Compose configuration (including the service
# definitions in docker-compose.yml) have moved to a
# dedicated repo:
#
# https://github.com/onetimesecret/docker-compose
# ----------------------------------------------------------------
#
#
# PRODUCTION DEPLOYMENT:
#
# When deploying to production, you should protect your Redis instance with
# authentication or Redis networks. You should also enable persistence and
# save the data somewhere, to make sure it doesn't get lost when the
# server restarts.
#
# You should also change the secret to something else, and specify the
# domain it will be deployed on. For instance, if OTS will be accessible
# from https://example.com:
#
# $ docker run -p 3000:3000 -d \
# -e REDIS_URL="redis://user:password@host:port/0" \
# -e COLONEL="[email protected]" \
# -e HOST=example.com \
# -e SSL=true \
# -e SECRET="<put your own secret here>" \
# -e RACK_ENV=production
# onetimesecret
#
##
# BASE LAYER
#
# Installs system packages, updates RubyGems, and prepares the
# application's package management dependencies using a Debian
# Ruby 3.2 base image.
#
ARG CODE_ROOT=/app
ARG ONETIME_HOME=/opt/onetime
FROM ruby:3.3-slim-bookworm@sha256:bc6372a998e79b5154c8132d1b3e0287dc656249f71f48487a1ecf0d46c9c080 AS builder
# Limit to packages needed for the system itself
# NOTE: We only need the build tools installed if we need
# to compile anything from source during the build.
# TODO: Use psycopg2-binary and remove psycopg2.
ARG PACKAGES="build-essential autoconf m4 sudo nodejs npm"
# Fast fail on errors while installing system packages
RUN set -eux && \
apt-get update && \
apt-get install -y $PACKAGES
RUN gem update --system
RUN gem install bundler
RUN npm install -g pnpm
##
# ENVIRONMENT LAYER
#
# Sets up the necessary directories, installs additional
# system packages for userland, and installs the application's
# dependencies using the Base Layer as a starting point.
#
FROM builder AS app_env
ARG CODE_ROOT
ARG ONETIME_HOME
# Limit to packages necessary for onetime and operational tasks
ARG PACKAGES="curl netcat-openbsd vim-tiny less redis-tools"
# Fast fail on errors while installing system packages
RUN set -eux && \
apt-get update && \
apt-get install -y $PACKAGES
# Create the directories that we need in the following image
RUN echo "Creating directories"
RUN mkdir -p "$CODE_ROOT"
RUN mkdir -p "$ONETIME_HOME/{log,tmp}"
WORKDIR $CODE_ROOT
COPY Gemfile ./
COPY Gemfile.lock ./
# Install the dependencies into the environment image
RUN bundle config set --local without 'development test'
RUN bundle install
RUN bundle update --bundler
# Invite Vite and Vue dependencies to the environment image
COPY package.json ./
COPY pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
ENV NODE_PATH=$CODE_ROOT/node_modules
COPY . .
RUN pnpm run type-check
RUN pnpm run build-only
##
# APPLICATION LAYER
#
# Contains the entire application context, including the code,
# configuration files, and all other files needed at run-time.
#
FROM app_env
ARG CODE_ROOT
LABEL Name=onetimesecret Version=0.16.2
LABEL maintainer "Onetime Secret <[email protected]>"
LABEL org.opencontainers.image.description "Onetime Secret is a web application to share sensitive information securely and temporarily. This image contains the application and its dependencies."
# See: https://fly.io/docs/rails/cookbooks/deploy/
ENV RUBY_YJIT_ENABLE=1
# Explicitly setting the Rack environment to production directs
# the application to use the pre-built JS/CSS assets in the
# "public/web/dist" directory. In dev mode, the application
# expects a vite server to be running on port 5173 and will
# attempt to connect to that server for each request.
#
# $ pnpm run dev
# VITE v5.3.4 ready in 38 ms
#
# ➜ Local: http://localhost:5173/dist/
# ➜ Network: use --host to expose
# ➜ press h + enter to show help
#
ENV RACK_ENV=production
WORKDIR $CODE_ROOT
# Copy the default config file into place if it doesn't
# already exist. If it does exist, nothing happens. For
# example, if the config file has been previously copied
# (and modified) the "--no-clobber" argument prevents
# those changes from being overwritten.
RUN cp --preserve --no-clobber \
etc/config.example etc/config
# About the interplay between the Dockerfile CMD, ENTRYPOINT,
# and the Docker Compose command settings:
#
# 1. The CMD instruction in the Dockerfile sets the default command to
# be executed when the container is started.
#
# 2. The command setting in the Docker Compose configuration overrides
# the CMD instruction in the Dockerfile.
#
# 3. Using the CMD instruction in the Dockerfile provides a fallback
# command, which can be useful if no specific command is set in the
# Docker Compose configuration.
# Rack app
EXPOSE 3000
CMD ["bin/entrypoint.sh"]