add touchless docker deploys

This commit is contained in:
shibao 2021-09-04 16:14:51 -04:00 committed by oliviasculley
parent eefde769dd
commit 6675c1dfab
12 changed files with 142 additions and 6953 deletions

5
.gitignore vendored
View File

@ -33,4 +33,7 @@ npm-debug.log
# this depending on your deployment strategy. # this depending on your deployment strategy.
/priv/static/ /priv/static/
.elixir_ls/ .elixir_ls/
# direnv
.envrc

53
Dockerfile Normal file
View File

@ -0,0 +1,53 @@
FROM elixir:1.12.2-alpine AS build
# install build dependencies
RUN apk add --no-cache build-base npm git python3
# prepare build dir
WORKDIR /app
# install hex + rebar
RUN mix local.hex --force && \
mix local.rebar --force
# set build ENV
ENV MIX_ENV=prod
# install mix dependencies
COPY mix.exs mix.lock ./
COPY config config
RUN mix do deps.get, deps.compile
# build assets
COPY assets/package.json assets/package-lock.json ./assets/
RUN npm --prefix ./assets ci --progress=false --no-audit --loglevel=error
COPY lib lib
COPY priv priv
COPY assets assets
RUN npm run --prefix ./assets deploy
RUN mix phx.digest
# compile and build release
# uncomment COPY if rel/ exists
# COPY rel rel
RUN mix do compile, release
# prepare release image
FROM alpine:3.9 AS app
RUN apk upgrade --no-cache && \
apk add --no-cache bash openssl libgcc libstdc++ ncurses-libs
WORKDIR /app
RUN chown nobody:nobody /app
USER nobody:nobody
COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/cannery ./
COPY --from=build --chown=nobody:nobody /app/priv /app/priv
ENV HOME=/app
CMD ["bin/cannery", "start"]

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
# is restricted to this project. # is restricted to this project.
# General application configuration # General application configuration
use Mix.Config import Config
config :cannery, config :cannery,
ecto_repos: [Cannery.Repo] ecto_repos: [Cannery.Repo]
@ -28,4 +28,4 @@ config :phoenix, :json_library, Jason
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs" import_config "#{config_env()}.exs"

View File

@ -1,12 +1,8 @@
use Mix.Config import Config
# Configure your database # Configure your database
config :cannery, Cannery.Repo, config :cannery, Cannery.Repo,
username: "postgres", url: "ecto://postgres:postgres@localhost/cannery_dev",
password: "postgres",
database: "cannery_dev",
hostname: "localhost",
show_sensitive_data_on_connection_error: true,
pool_size: 10 pool_size: 10
# For development, we disable any cache and enable # For development, we disable any cache and enable

View File

@ -1,4 +1,4 @@
use Mix.Config import Config
# For production, don't forget to configure the url host # For production, don't forget to configure the url host
# to something meaningful, Phoenix uses this information # to something meaningful, Phoenix uses this information
@ -10,8 +10,13 @@ use Mix.Config
# which you should run after static files are built and # which you should run after static files are built and
# before starting your production server. # before starting your production server.
config :cannery, CanneryWeb.Endpoint, config :cannery, CanneryWeb.Endpoint,
url: [host: "example.com", port: 80], url: [host: "localhost"],
http: [port: 4000],
cache_static_manifest: "priv/static/cache_manifest.json" cache_static_manifest: "priv/static/cache_manifest.json"
config :cannery, Cannery.Repo,
url: "ecto://postgres:postgres@localhost/cannery",
pool_size: 10
# Do not print debug messages in production # Do not print debug messages in production
config :logger, level: :info config :logger, level: :info
@ -23,7 +28,7 @@ config :logger, level: :info
# #
# config :cannery, CanneryWeb.Endpoint, # config :cannery, CanneryWeb.Endpoint,
# ... # ...
# url: [host: "example.com", port: 443], # url: [host: "localhost", port: 443],
# https: [ # https: [
# port: 443, # port: 443,
# cipher_suite: :strong, # cipher_suite: :strong,
@ -49,7 +54,3 @@ config :logger, level: :info
# force_ssl: [hsts: true] # force_ssl: [hsts: true]
# #
# Check `Plug.SSL` for all available options in `force_ssl`. # Check `Plug.SSL` for all available options in `force_ssl`.
# Finally import the config/prod.secret.exs which loads secrets
# and configuration from environment variables.
import_config "prod.secret.exs"

View File

@ -2,14 +2,11 @@
# from environment variables. You can also hardcode secrets, # from environment variables. You can also hardcode secrets,
# although such is generally not recommended and you have to # although such is generally not recommended and you have to
# remember to add this file to your .gitignore. # remember to add this file to your .gitignore.
use Mix.Config import Config
database_url = database_url =
System.get_env("DATABASE_URL") || System.get_env("DATABASE_URL") ||
raise """ "ecto://postgres:postgres@cannery-db/cannery"
environment variable DATABASE_URL is missing.
For example: ecto://USER:PASS@HOST/DATABASE
"""
config :cannery, Cannery.Repo, config :cannery, Cannery.Repo,
# ssl: true, # ssl: true,
@ -28,14 +25,5 @@ config :cannery, CanneryWeb.Endpoint,
port: String.to_integer(System.get_env("PORT") || "4000"), port: String.to_integer(System.get_env("PORT") || "4000"),
transport_options: [socket_opts: [:inet6]] transport_options: [socket_opts: [:inet6]]
], ],
secret_key_base: secret_key_base secret_key_base: secret_key_base,
server: true
# ## Using releases (Elixir v1.9+)
#
# If you are doing OTP releases, you need to instruct Phoenix
# to start each relevant endpoint:
#
# config :cannery, CanneryWeb.Endpoint, server: true
#
# Then you can assemble a release by calling `mix release`.
# See `mix help release` for more information.

View File

@ -1,4 +1,4 @@
use Mix.Config import Config
# Only in tests, remove the complexity from the password hashing algorithm # Only in tests, remove the complexity from the password hashing algorithm
config :bcrypt_elixir, :log_rounds, 1 config :bcrypt_elixir, :log_rounds, 1

29
docker-compose.yml Normal file
View File

@ -0,0 +1,29 @@
version: '3'
services:
cannery:
build:
context: .
container_name: cannery
environment:
DATABASE_URL: "ecto://postgres:postgres@cannery-db/cannery"
# generate a random base64 string 64 characters long, preferably not from a website
SECRET_KEY_BASE: "change-me-to-something-random-this-is-really-important-change-it"
ports:
# do not expose this publically!
# always host from behind a reverse proxy with a properly configured certificate
- "4000:4000"
restart: always
depends_on:
- cannery-db
cannery-db:
image: postgres:9.6
container_name: cannery-db
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: cannery
restart: always
volumes:
- ./data:/var/lib/postgresql/data

View File

@ -9,6 +9,7 @@ defmodule Cannery.Application do
children = [ children = [
# Start the Ecto repository # Start the Ecto repository
Cannery.Repo, Cannery.Repo,
Cannery.Repo.Migrator,
# Start the Telemetry supervisor # Start the Telemetry supervisor
CanneryWeb.Telemetry, CanneryWeb.Telemetry,
# Start the PubSub system # Start the PubSub system

20
lib/cannery/release.ex Normal file
View File

@ -0,0 +1,20 @@
defmodule Cannery.Release do
@app :cannery
def rollback(repo, version) do
load_app()
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
end
defp load_app do
Application.load(@app)
end
def migrate do
load_app()
for repo <- Application.fetch_env!(@app, :ecto_repos) do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end
end
end

View File

@ -0,0 +1,18 @@
defmodule Cannery.Repo.Migrator do
use GenServer
require Logger
def start_link(_) do
GenServer.start_link(__MODULE__, [], [])
end
def init(_) do
migrate!()
{:ok, nil}
end
def migrate! do
path = Application.app_dir(:cannery, "priv/repo/migrations")
Ecto.Migrator.run(Cannery.Repo, path, :up, all: true)
end
end