1
0
mirror of https://github.com/mxpv/podsync.git synced 2024-05-11 05:55:04 +00:00

Prepare for production

- Add caddy server
- Add Docker
- Minor fixes in status endpoint
This commit is contained in:
Maksym Pavlenko
2016-12-23 21:31:44 -08:00
parent e40becede6
commit 588d2efd54
10 changed files with 171 additions and 17 deletions

View File

@@ -0,0 +1,2 @@
FROM zzrot/alpine-caddy
COPY Caddyfile /etc/Caddyfile

32
src/Podsync/Caddyfile Normal file
View File

@@ -0,0 +1,32 @@
new.podsync.net
gzip
errors stdout
ratelimit 2 3 second {
/feed
/download
}
proxy / {%REDIRECT_HOST%}:{%REDIRECT_PORT%} {
header_upstream Host {host}
transparent
}
tls pavlenko.maksym@gmail.com
header / {
# Remove ASP.NET specific headers
-Server
-X-Powered-By
-X-Sourcefiles
# Enable cross-site filter (XSS) and tell browser to block detected attacks
X-XSS-Protection "1; mode=block"
# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type
X-Content-Type-Options "nosniff"
# Disallow the site to be rendered within a frame (clickjacking protection)
X-Frame-Options "DENY"
}

View File

@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Podsync.Services.Resolver;
using Podsync.Services.Storage;
@@ -7,6 +8,8 @@ namespace Podsync.Controllers
{
public class StatusController : Controller
{
private const string ErrorStatus = "ERROR";
private readonly IStorageService _storageService;
private readonly IResolverService _resolverService;
@@ -18,11 +21,23 @@ namespace Podsync.Controllers
public async Task<string> Index()
{
var time = await _storageService.Ping();
var storageStatus = ErrorStatus;
try
{
var time = await _storageService.Ping();
storageStatus = time.ToString();
}
catch (Exception)
{
// Nothing to do
}
var resolverStatus = _resolverService.Version ?? ErrorStatus;
return $"Path: {Request.Path}\r\n" +
$"Redis: {time}\r\n" +
$"Resolve: {_resolverService.Version}";
$"Redis: {storageStatus}\r\n" +
$"Resolve: {resolverStatus}";
}
}
}

14
src/Podsync/Deploy.txt Normal file
View File

@@ -0,0 +1,14 @@
$> ./Up.ps1
$> docker-machine create --driver digitalocean
--digitalocean-accescean-image=ubuntu-16-04-x64
--digitalocean-region=ams2
--digitalocean-backups=true
--digitalocean-size=512mb
podsync
$> docker-machine env podsync
$> $env:COMPOSE_CONVERT_WINDOWS_PATHS=0
$> docker-compose up -d

16
src/Podsync/Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
FROM microsoft/aspnetcore:1.0.3
ARG PORT=56247
ARG PUBLISH_DIR="bin/Publish"
WORKDIR /app
ENV ASPNETCORE_URLS http://+:$PORT
EXPOSE $PORT
COPY $PUBLISH_DIR .
# Install Python for youtube-dl
RUN apt-get update && apt-get install -y python && chmod a+rx youtube-dl
ENTRYPOINT ["dotnet", "Podsync.dll"]

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using HashidsNet;
using Microsoft.Extensions.Options;
@@ -28,31 +30,62 @@ namespace Podsync.Services.Storage
private static readonly IHashids HashIds = new Hashids(IdSalt, IdLength);
private readonly IDatabase _db;
private readonly string _cs;
private IDatabase _db;
public RedisStorage(IOptions<PodsyncConfiguration> configuration)
{
var cs = configuration.Value.RedisConnectionString;
var connection = ConnectionMultiplexer.ConnectAsync(cs).GetAwaiter().GetResult();
_cs = configuration.Value.RedisConnectionString;
}
_db = connection.GetDatabase();
private IDatabase Db
{
get { return LazyInitializer.EnsureInitialized(ref _db, () => Connect(_cs).GetAwaiter().GetResult().GetDatabase()); }
}
private static async Task<ConnectionMultiplexer> Connect(string cs)
{
var options = ConfigurationOptions.Parse(cs);
try
{
return await ConnectionMultiplexer.ConnectAsync(options);
}
catch (PlatformNotSupportedException)
{
// Can't connect via address on Linux environments, using workaround
// See https://github.com/StackExchange/StackExchange.Redis/issues/410#issuecomment-246332140
var addressEndpoint = options.EndPoints.SingleOrDefault() as DnsEndPoint;
if (addressEndpoint != null)
{
var ip = await Dns.GetHostEntryAsync(addressEndpoint.Host);
options.EndPoints.Remove(addressEndpoint);
options.EndPoints.Add(ip.AddressList.First(), addressEndpoint.Port);
}
return await ConnectionMultiplexer.ConnectAsync(options);
}
}
public void Dispose()
{
_db.Multiplexer.Dispose();
if (_db != null)
{
_db.Multiplexer.Dispose();
_db = null;
}
}
public Task<TimeSpan> Ping()
{
return _db.PingAsync();
return Db.PingAsync();
}
public async Task<string> Save(FeedMetadata metadata)
{
var id = await MakeId();
await _db.HashSetAsync(id, new[]
await Db.HashSetAsync(id, new[]
{
new HashEntry(ProviderField, metadata.Provider.ToString()),
new HashEntry(TypeField, metadata.LinkType.ToString()),
@@ -61,7 +94,7 @@ namespace Podsync.Services.Storage
new HashEntry(PageSizeField, metadata.PageSize),
});
await _db.KeyExpireAsync(id, TimeSpan.FromDays(1));
await Db.KeyExpireAsync(id, TimeSpan.FromDays(1));
return id;
}
@@ -73,10 +106,10 @@ namespace Podsync.Services.Storage
throw new ArgumentException("Feed key can't be empty");
}
var entries = await _db.HashGetAllAsync(key);
var entries = await Db.HashGetAllAsync(key);
// Expire after 3 month if no use
await _db.KeyExpireAsync(key, TimeSpan.FromDays(90));
await Db.KeyExpireAsync(key, TimeSpan.FromDays(90));
if (entries.Length == 0)
{
@@ -107,12 +140,12 @@ namespace Podsync.Services.Storage
public Task ResetCounter()
{
return _db.KeyDeleteAsync(IdKey);
return Db.KeyDeleteAsync(IdKey);
}
public async Task<string> MakeId()
{
var id = await _db.StringIncrementAsync(IdKey);
var id = await Db.StringIncrementAsync(IdKey);
return HashIds.EncodeLong(id);
}

13
src/Podsync/Up.ps1 Normal file
View File

@@ -0,0 +1,13 @@
$OUTPUT_DIR = 'bin/Publish'
& "dotnet" restore
Remove-Item $OUTPUT_DIR -Force -Recurse -ErrorAction Ignore
& "dotnet" publish --configuration release --output $OUTPUT_DIR
& "docker" build -t podsync .
# docker run -d -p 5001:5001 podsync
& "docker-compose" up -d

View File

@@ -0,0 +1,27 @@
version: '2'
services:
app:
image: podsync
build:
context: .
dockerfile: Dockerfile
args:
- PORT=56247
environment:
- Podsync:RedisConnectionString=redis
redis:
image: redis
command: redis-server --appendonly yes
volumes:
- /redis_data:/data
caddy:
build:
context: .
dockerfile: Caddy.Dockerfile
ports:
- 80:80
- 443:443
environment:
- REDIRECT_HOST=app
- REDIRECT_PORT=56247

View File

@@ -57,7 +57,9 @@
"Views",
"Areas/**/Views",
"appsettings.json",
"web.config"
"web.config",
"Dockerfile",
"youtube-dl"
]
},
"scripts": {

BIN
src/Podsync/youtube-dl Normal file
View File

Binary file not shown.