Skip to content

Commit e55d962

Browse files
authored
Use env files instead of environment variables declared in docker-compose. Closes #1088 (#1091)
It's best practice to leave secrets and environment variables outside of a docker compose file, because if there are secrets we can't add the file to a VCS. This PR adds a new entrypoint to the Docker container to create required env variables for postgres and stringer if they don't already exist. It also changes the docker-compose.yml file to use these env files instead of environment variables passed in one by one. I also renamed the containers from postgres and web to stringer-postgres and stringer which are more identifiable in a setup that may have multiple services or applications running in docker. Finally, I also updated the docker compose docs and upgraded the docker compose file version to 3. The new instructions for easy setup via docker compose are: - clone the repo - `touch .env` - `docker compose up -d` - visit `localhost`
1 parent 600348d commit e55d962

File tree

4 files changed

+67
-17
lines changed

4 files changed

+67
-17
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ spec/examples.txt
2828

2929
# Ignore local .env files
3030
*.local
31+
.env

docker-compose.yml

+25-16
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,46 @@
1-
version: '2'
1+
version: '3'
22

33
services:
4-
postgres:
4+
stringer-setup:
5+
image: stringerrss/stringer:latest
6+
container_name: stringer-setup
7+
restart: no
8+
env_file: .env
9+
volumes:
10+
- ./.env:/app/.env
11+
entrypoint: ["ruby"]
12+
command: ["/app/docker/init_or_update_env.rb"]
13+
14+
stringer-postgres:
515
image: postgres:9.5-alpine
16+
container_name: stringer-postgres
617
restart: always
18+
depends_on:
19+
stringer-setup:
20+
condition: service_completed_successfully
721
networks:
822
- stringer-network
923
volumes:
1024
- ~/stringer:/var/lib/postgresql/data
11-
environment:
12-
- POSTGRES_PASSWORD=super_secret_password
13-
- POSTGRES_USER=db_user
14-
- POSTGRES_DB=stringer
25+
env_file: .env
1526

16-
web:
27+
stringer:
1728
image: stringerrss/stringer:latest
29+
container_name: stringer
1830
build: .
1931
depends_on:
20-
- postgres
32+
stringer-postgres:
33+
condition: service_started
34+
stringer-setup:
35+
condition: service_completed_successfully
2136
restart: always
2237
ports:
2338
- 80:8080
2439
networks:
2540
- stringer-network
26-
environment:
27-
- SECRET_KEY_BASE=<your configuration>
28-
- ENCRYPTION_PRIMARY_KEY=<your configuration>
29-
- ENCRYPTION_DETERMINISTIC_KEY=<your configuration>
30-
- ENCRYPTION_KEY_DERIVATION_SALT=<your configuration>
31-
- PORT=8080
32-
- DATABASE_URL=postgres://db_user:super_secret_password@postgres:5432/stringer
41+
env_file: .env
3342

3443
networks:
3544
stringer-network:
3645
external: false
37-
name: stringer-network
46+
name: stringer-network

docker/init_or_update_env.rb

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
module Secrets
4+
def self.generate_secret(length)
5+
`openssl rand -hex #{length}`.strip
6+
end
7+
end
8+
9+
pg_user = ENV.fetch("POSTGRES_USER", "stringer")
10+
pg_password = ENV.fetch("POSTGRES_PASSWORD", Secrets.generate_secret(32))
11+
pg_host = ENV.fetch("POSTGRES_HOSTNAME", "stringer-postgres")
12+
pg_db = ENV.fetch("POSTGRES_DB", "stringer")
13+
14+
required_env = {
15+
"SECRET_KEY_BASE" => Secrets.generate_secret(64),
16+
"ENCRYPTION_PRIMARY_KEY" => Secrets.generate_secret(64),
17+
"ENCRYPTION_DETERMINISTIC_KEY" => Secrets.generate_secret(64),
18+
"ENCRYPTION_KEY_DERIVATION_SALT" => Secrets.generate_secret(64),
19+
"POSTGRES_USER" => pg_user,
20+
"POSTGRES_PASSWORD" => pg_password,
21+
"POSTGRES_HOSTNAME" => pg_host,
22+
"POSTGRES_DB" => pg_db,
23+
"FETCH_FEEDS_CRON" => "*/5 * * * *",
24+
"CLEANUP_CRON" => "0 0 * * *",
25+
"DATABASE_URL" => "postgres://#{pg_user}:#{pg_password}@#{pg_host}/#{pg_db}"
26+
}
27+
28+
required_env.each do |key, value|
29+
next if ENV.key?(key)
30+
31+
File.open("/app/.env", "a") { |file| file << "#{key}=#{value}\n" }
32+
end

docs/Docker.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22

33
## Production ready setup using docker-compose
44

5-
Download [docker-compose.yml](../docker-compose.yml) and in the corresponding folder, run `docker-compose up -d`, give it a second and visit `localhost`
5+
Create a local environment file named `.env`, e.g. via `touch .env`.
6+
7+
Download [docker-compose.yml](../docker-compose.yml) and run:
8+
9+
```sh
10+
touch .env && docker compose up -d
11+
```
12+
13+
Give it a second and visit `localhost`!
614

715
## Production ready manual setup
816

0 commit comments

Comments
 (0)